我有一个带有构造函数的类,该构造函数带有子接口的集合
public class Manager : IManager
{
public Manager(IEnumerable<IDataAccess> dataAccess)
{
IDataAccess是基本接口
public interface IFooDataAccess : IDataAccess
{
public interface IBarDataAccess : IDataAccess
{
public interface IBazDataAccess : IDataAccess
{
这些都有具体的实现。
当我解析IManager时,我希望dataAccess参数填充有FooDataAccess,BarDataAccess和BazDataAccess的集合。
我正在将unity用作IoC,当前注册为:
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterTypes(AllClasses.FromAssemblies(
typeof(IManager).Assembly),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled);
我的解决方案中确实还有其他一些类(因此使用了注册模式),所以我想保留这个类。我一直在尝试自己注册IManager:
var allDataAccesses = container.ResolveAll<IDataAccess>();
var parameter = new InjectionConstructor(allDataAccesses);
container.RegisterType<IManager, Manager>(parameter);
但是我无法正常工作,我想念的是什么。如何配置统一性来解析构造函数?
最佳答案
您所做的注册将映射直接实现的接口,而不是IDataAccess
。
例如,它将IFooDataAccess
映射到FooDataAccess
。例如,您需要将IDataAccess
映射到FooDataAccess
。
要解决此问题,请添加以下注册代码:
container.RegisterTypes(
typeof (IManager)
.Assembly
.GetTypes()
.Where(x => x.IsClass)
.Where(x => typeof (IDataAccess).IsAssignableFrom(x)),
x => new[] {typeof (IDataAccess)},
WithName.TypeName, WithLifetime.ContainerControlled);
这将在程序集中搜索实现
IDataAccess
的类(直接或间接),并在IDataAccess
和这些类之间创建映射。这里要注意的重要一件事是它为注册赋予了名称。这很重要,因为如果将接口
IDataAccess
映射到许多类,则不能使用默认名称。团结如何知道要使用哪个地图条目?您需要做的另一件事是像这样将
IEnumerable<IDataAccess>
映射到IDataAccess[]
:container.RegisterType<IEnumerable<IDataAccess>, IDataAccess[]>();
Unity知道如何通过查看所需接口的命名注册来解析数组。默认情况下,它不能对
IEnumerable<T>
执行相同的操作。一种替代方法是更改构造函数以使用如下数组:public class Manager : IManager
{
public Manager(IDataAccess[] dataAccess)
{
....
}
....
}