简体   繁体   中英

DotNet Core Dependency Injection Factory Types

I am trying to create a generic factory using dependency injection, and I seem to be running into a bit of an issue.

so I have a DataProvider<TModel,TId> that may look something like:

 public interface IDataProvider<TModel, TId>
      where TModel:class, new()
 {
      TModel Get(TId id);

      IEnumerator<TModel> Get();

      TModel Create(TModel model);

      TModel Update(TModel model);

      int Delete(TId id);
 }

and I have a factory that looks something like

 public interface IDataProviderFactory
 {
      IDataProvider<TModel, TId> GetProvider<TModel,TId>() where TModel:class,new();
 }

now on to my issue, I would like to beable to add IDataProvider<Customer,int> in the constructer of where ever I want to use it at.

I cannot seem to figure this out, but what I have so far is something like;

           services.AddTransient(typeof(IDataProvider<,>), (serviceProvider)=>
           {
                var factory = serviceProvider.GetService<IDataProviderFactory>();

                //I am not sure how to reference the type from above
                
                return factory.GetProvider<>();
           });

How can I get the requested type and pass it into the factory.GetProvider<>() method?

It's impossible in MS.DI to register an open-generic function, as you show in your code example. You will have to make a mapping between an open-generic abstraction and an open-generic implementation, eg:

services.AddTransient(typeof(IDataProvider<,>), typeof(ProxyDataProvider<,>));

This will, of course, cause MS.DI to be responsible of creating ProxyDataProvider<,> . But what you can do is make ProxyDataProvider<,> a proxy that forwards the call to IDataProviderFactory , which will be again in control of the creation of the data providers. The DataProvider<,> can be implemented as follows:

public class ProxyDataProvider<TModel, TId> : IDataProvider<TModel, TId>
    where TModel:class, new()
{
    private readonly IDataProviderFactory factory;
    
    public ProxyDataProvider(IDataProviderFactory factory) =>
        this.factory = factory;
        
    private IDataProvider<TModel, TId> Provider =>
        this.factory.GetProvider<TModel, TId>();
        
    public TModel Get(TId id) => this.Provider.Get(id);
    public IEnumerator<TModel> Get() => this.Provider.Get();
    public TModel Create(TModel model) => this.Provider.Create(model);
    public TModel Update(TModel model) => this.Provider.Update(model);
    public int Delete(TId id) => this.Provider.Delete(id);
}

Additionally, you can cache the factory's created data provider inside of the proxy. That prevents an instance from being created on each call. On the other hand, this will cause the proxy to contain state, which makes it important to register it using AddScoped :

services.AddScoped(typeof(IDataProvider<,>), typeof(ProxyDataProvider<,>));

You can register your generic types, and do not use factory services.AddTransient(typeof(IDataProvider<,>), typeof(DataProvider<,>)); another way you can use reflection but that is not best way for use it. BTW i would suggest if you use factory, use factory in all places if not just remove it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM