我有一个带有构造函数的类,它接受子接口(interface)的集合
public class Manager : IManager
{
public Manager(IEnumerable<IDataAccess> dataAccess)
{
IDataAccess 是一个基础接口(interface)
public interface IFooDataAccess : IDataAccess
{
public interface IBarDataAccess : IDataAccess
{
public interface IBazDataAccess : IDataAccess
{
其中每一个都有具体的实现。 当我解析 IManager 时,我希望使用 FooDataAccess、BarDataAccess 和 BazDataAccess 的集合填充 dataAccess 参数。
我正在使用 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);
但我无法让它工作,我错过了什么。如何配置 unity 来解析构造函数?
请您参考如下方法:
您所做的注册将映射直接实现的接口(interface)而不是 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 之间创建一个映射和这些类(class)。
这里要注意的一件重要事情是它为注册提供了一个名称。这很重要,因为如果您有接口(interface) IDataAccess映射到许多类,则不能使用默认名称。 unity 如何知道要使用哪个映射条目?
您需要做的另一件事是映射 IEnumerable<IDataAccess>至 IDataAccess[]像这样:
container.RegisterType<IEnumerable<IDataAccess>, IDataAccess[]>();
Unity 知道如何通过查看所需接口(interface)的命名注册来解析数组。默认情况下,它不能对 IEnumerable<T> 执行相同的操作.另一种方法是更改构造函数以使用如下数组:
public class Manager : IManager
{
public Manager(IDataAccess[] dataAccess)
{
....
}
....
}
