Stuck on generics and interfaces. Need a code-based solution, maybe interface redesign

This is the part of my code where I need help:

// simple service locator
public class ServiceManager<TSvc> : IServiceManager<TSvc> where TSvc: class, IService
{
   private Dictionary<object, TSvc> services;

   public void RegisterService(TSvc service)
    {
        // omitted code here
        this.services.Add(service.GetType(), service); // dictionary
    }
    public T GetService<T>() where T : TSvc
    {
        T result = default(T);

        TSvc bufResult = null;
        if (this.services.TryGetValue(typeof(T), out bufResult))
            result = (T)bufResult;

        return result;
    }
    public TSvc GetService(Type serviceType)
    {
        TSvc result = null;

        this.services.TryGetValue(serviceType, out result);

        return result;
    }
}

Then my domain interfaces:

public interface IItem
{
   string Name { get; set; }
}
public interface IRepository<TModel> where TModel : IItem
{
    new IEnumerable<TModel> GetItems();
    void InsertItem(TModel item);
    void UpdateItem(TModel item);
    void DeleteItem(TModel item);
}
public interface IService<TModel> where TModel : IItem
{
    IRepository<TModel> Repository { get; }
}

Then some of my domain classes:

public class Book: IItem
{
    public string Name { get; set; }
}
public class BookRepo: IRepository<Book>
{
    new IEnumerable<Book> GetItems();
    void InsertItem(Book item);
    void UpdateItem(Book item);
    void DeleteItem(Book item);
}
public class BookService: IService<Book>
{
    IRepository<Book> IService<Book>.Repository { get { return this.Repository; } }
    BookRepo Repository { get; set;} 
}

Now, if I am interested in using "BookService" and doing something with it, I could get it from the services locator as follows:

public void DoSomething()
{
    var bookService = serviceManager.GetService<BookService>();
    bookService.Repository.Insert(new Book()); 
}

But the problem is that the type of service is known only at runtime (for example, choosing from combobox). So what does the DoSomething method look like?

public void DoSomething()
{
    var typeOfService = combobox.SelectedValue.GetType(); // cbx of services
    // ??? make use of serviceManager and typeOfService to get appropriate 'service'
    service.Repository.Insert(/*new IITem here*/);
}

Also, I would like to know how you would connect IServiceto IService<TModel>... he might even get to a solution, but I have no idea how to do this. My interface is IServiceempty at the moment ...

I would really appreciate your time. Please let me know if something is unclear! Thank!

:. , (- NSGaga), , IService IService<TModel>, , . , ?

+5
2

- ( , , - )

MethodInfo methodInfo = typeof(ServiceManager).GetMethod("GetService");
MethodInfo methodInfoGeneric = methodInfo.MakeGenericMethod(new[] { typeOfService });
methodInfoGeneric.Invoke(serviceManager, new object[] { });
+2

, , .

, , GetService<BookService>, new Book() . , , , . : , , insert .

. , , :

void CreateNewObject<T>() where T : new()
{
    var service = GetServiceFor<T>();
    service.Repository.Insert(new T());
}

, .

+2

All Articles