Unity具有相同的界面,多个工厂

时间:2016-01-20 22:48:02

标签: c# asp.net dependency-injection unity-container ioc-container

所以问题是,当我宣布:

[Dependency]
public AuthenticationService _authenticationServices { get; set; }

_authenticationServices将始终保持null。它没有被引用,这将抛出Null Reference Exception。我假设问题源于我的Unity配置文件:

container.RegisterType<ICrudFactory, ZNodeDataContextFactory>();
container.RegisterType<ICrudFactory, MincronDataContextFactory>();

既然它们都使用相同的接口,而是单独的具体实现。实施如下:

public interface ICrud : IDisposable
{
     // Method's to be exposed, via general repository.
}

public interface ICrudFactory
{
     ICrud Create();
}

public ZNodeDataContext : DbContext, ICrud
{
     // Concrete implementation.
}

public MincronDataContext : DbContext, ICrud
{
     // Concrete implementation.
}

public ZNodeDataContextFactory : ICrudFactory
{
     ICrud ICrudFactory.Create()
     {
           return ZNodeDataContext();
     }
}

public MincronDataContextFactory : ICrudFactory
{
     ICrud ICrudFactory.Create()
     {
           return MincronDataContext();
     }
}

public class AuthenticationService
{
     private readonly ICrudFactory _factory;
     public AuthenticationService(ICrudFactory factory)
     {
         _factory = factory;
     }

     public void Sample()
     {
          using(var context = _factory.Create())
              context.Method(...);
     }
}

我希望保留这种结构,以避免代码重复。

2 个答案:

答案 0 :(得分:1)

您想将ZNodeDataContextFactory注入AuthenticationService吗?注入的一点是,服务现在不应该关于实现。但是如果你真的想要一个特定的实现,你可以创建一个命名实例。

public class AuthenticationService
{
     private readonly ICrudFactory _factory;
     public AuthenticationService([Dependency("ZNodeData")] ICrudFactory factory)
     {
         _factory = factory;
     }
}

在您的配置中:

container.RegisterType<ICrudFactory, ZNodeDataContextFactory>("ZNodeData");
container.RegisterType<ICrudFactory, MincronDataContextFactory>("MincronData");

可替换地:

    public class AuthenticationService
    {
         private readonly IEnumerable<ICrudFactory> _factories;
         public AuthenticationService(ICrudFactory[] factories)
         {
             // Now you got both...
             _factories = factories;
             var zNodeFactory = _factories.FirstOrDefault(x => x.Factory == ZNode);
         }
    }


    public interface ICrudFactory
    {
         ICrud Create();
         // Something to identify the type of data. Maybe an enum?
         FactoryType Factory {get;}
    }

public ZNodeDataContextFactory : ICrudFactory
{
     ICrud ICrudFactory.Create()
     {
           return ZNodeDataContext();
     }

     FactoryType ICrudFactory.Factory
     {
        {get {return FactoryType.ZNode;}
     }
}

答案 1 :(得分:0)

我最终通过为每个通用存储库创建特定容器来解决问题。

public interface IZNodeContextFactory : ICrudFactory
{

}

public interface IMincronContextFactory : ICrudFactory
{

}

通过这种方式,我能够做到:

container.RegisterType<IZNodeContextFactory, ZNodeContextFactory>();
container.RegisterType<IMincronContextFactory, MincronContextFactory>();

这允许自动依赖性解析器工作,并实现,因为它们现在具有唯一的名称。