使用ASP.NET Core DI注册接口的通用和特定实现

时间:2016-12-13 16:16:25

标签: c# asp.net-core inversion-of-control asp.net-core-mvc

我已经阅读了Armen Shimoon的文章ASP.NET Core: Factory Pattern Dependency Injection,并且我决定使用他建议的技术解决我的ASP.NET Core DI问题。 我有一个通用接口:

public interface IItemRepository<out T> where T : BaseItem

及其通用实现:

public class ItemRepository<T> : IItemRepository<T> where T : BaseItem

我将其注册为:

services.AddSingleton(typeof(IItemRepository<>), typeof(ItemRepository<>));

但是对于货币,我有一个具体的实现:

public class CurrencyRepository : ItemRepository<Currency>

(Curency属于 BaseItem 类型。)我想要的是注册

CurrencyRepository

代表

IItemRepository<Currency>

ItemRepository<T>

用于实施 BaseItem 的所有其他项目。我创建了一个工厂类来实现这个目标:

public class ItemRepositoryFactory : IServiceFactory> where T : BaseItem
{
    private readonly ApplicationDbContext _context;

    public ItemRepositoryFactory(ApplicationDbContext context)
    {
        _context = context;
    }

    public ItemRepository Build()
    {
        if (typeof(T) == typeof(Currency))
            return new CurrencyRepository(_context) as ItemRepository;

        return new ItemRepository(_context);
    }
}

但我不知道如何使用 IServiceCollection 注册它。或者我可能根本不是正确的方式?

1 个答案:

答案 0 :(得分:0)

您无法明确注册。 ASP.NET Core DI意味着简单,提供开箱即用的DI / IoC体验,并且易于插入其他DI / IoC容器。

因此内置的IoC不提供自动注册,装配扫描,装饰器或类的所有接口/子类型的注册。

对于具体实施,有一个&#34;解决方法&#34;

services.AddScoped<IMyService,MyService>();
services.AddScoped<MyService>(provider => provider.GetService<IMyService>());

然后构造函数中的MyServiceIMyService将接收该类的相同实例。

但这并不适用于开放式仿制药,而且是一个手动过程。对于自动发现或注册,您需要第三方IoC容器,例如Autofac,StructureMap等。

但是在你的具体样本中,在IItemRepository<Currency>方法中注册ConfigureServices就足够了

services.AddScoped<IItemRepository<Currency>,CurrencyRepository>();

但实际上,如果您将IItemRepository<Currency>注入服务中,那么开放式通用应该已经涵盖了这种情况。