简体   繁体   English

DotNet 核心依赖注入工厂类型

[英]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:所以我有一个DataProvider<TModel,TId>可能看起来像:

 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.现在IDataProvider<Customer,int>我的问题,我希望能够在我想在何处使用它的构造函数中添加IDataProvider<Customer,int>

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?如何获取请求的类型并将其传递给factory.GetProvider<>()方法?

It's impossible in MS.DI to register an open-generic function, as you show in your code example.正如您在代码示例中所示,在 MS.DI 中不可能注册一个开放的通用函数。 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<,> .当然,这将导致 MS.DI 负责创建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.但是您可以做的是使ProxyDataProvider<,>成为将调用转发到IDataProviderFactory的代理,该代理将再次控制数据提供者的创建。 The DataProvider<,> can be implemented as follows: DataProvider<,>可以实现如下:

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 :另一方面,这将导致代理包含状态,这使得使用AddScoped注册它很重要:

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

You can register your generic types, and do not use factory services.AddTransient(typeof(IDataProvider<,>), typeof(DataProvider<,>));你可以注册你的泛型类型,不要使用工厂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顺便说一句,我建议如果您使用工厂,请在所有地方使用工厂,如果不只是将其删除

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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