统一接口,多工厂
Unity with the same interface, multiple factories
所以问题是我何时声明:
[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(...);
}
}
我想保留该结构,以避免代码重复。
您要将 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;}
}
}
我最终通过为每个通用存储库创建特定容器解决了这个问题。
public interface IZNodeContextFactory : ICrudFactory
{
}
public interface IMincronContextFactory : ICrudFactory
{
}
通过这种方式,我可以简单地做到:
container.RegisterType<IZNodeContextFactory, ZNodeContextFactory>();
container.RegisterType<IMincronContextFactory, MincronContextFactory>();
这允许自动依赖项解析器工作和实施,因为它们现在具有唯一的名称。
所以问题是我何时声明:
[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(...);
}
}
我想保留该结构,以避免代码重复。
您要将 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;}
}
}
我最终通过为每个通用存储库创建特定容器解决了这个问题。
public interface IZNodeContextFactory : ICrudFactory
{
}
public interface IMincronContextFactory : ICrudFactory
{
}
通过这种方式,我可以简单地做到:
container.RegisterType<IZNodeContextFactory, ZNodeContextFactory>();
container.RegisterType<IMincronContextFactory, MincronContextFactory>();
这允许自动依赖项解析器工作和实施,因为它们现在具有唯一的名称。