我试图按照约定注册单个接口的多个实现,然后在其他类中使用所有这些接口作为依赖项。不幸的是,我在尝试这样做时遇到了一些困难。
我想注册多个实现,所以我添加了WithName.TypeName注册,但这似乎会导致问题。没有它,我就无法为单个接口注册多个实现。
下面是不起作用的简单例子。团结就是破例,我不知道为什么。
Unity.ResolutionFailedException:‘解析失败,错误:没有公共构造函数可用于KYPClient.IConf类型。
namespace KYPClient
{
public interface IConf
{
string conf();
}
public class Conf : IConf
{
public string conf()
{
return "conf";
}
}
public interface ILoader
{
string load();
}
public class Load_1 : ILoader
{
public string load()
{
return "load-1";
}
}
public class Load_2 : ILoader
{
public string load()
{
return "load-2";
}
}
public class MainCls
{
private IConf _conf;
private IEnumerable<ILoader> _loaders;
public MainCls(IConf conf, IEnumerable<ILoader> loaders)
{
_conf = conf;
_loaders = loaders;
}
public void Run()
{
System.Console.WriteLine(_conf.conf());
foreach (var l in _loaders)
{
Console.WriteLine(l.load());
}
}
}
internal static class Client
{
private static void Main()
{
using var container = new UnityContainer();
container.RegisterTypes(
AllClasses.FromAssemblies(typeof(MainCls).Assembly),
WithMappings.FromAllInterfaces,
WithName.TypeName,
WithLifetime.ContainerControlled);
var main = container.Resolve<MainCls>();
main.Run();
}
}}
发布于 2019-12-17 23:33:28
问题是您使用的是WithName.TypeName选项。这意味着程序集中的每个类型都是作为容器中的命名注册完成的。这在您的情况下是一件好事,因为您正在注册多个ILoader实例,因此容器必须能够区分它们。但是,这也意味着当它被解析时,您必须传递名称才能让容器找到它。
换句话说,当容器看到构造函数public MainCls(IConf conf, IEnumerable<ILoader> loaders)时,它解释为“用默认名称注入IConf实例”,而这个名称并不存在于容器中。您的IConf注册名称为"Conf“(或者可能是"KYPClient.Conf",我不确定,因为我从未使用过RegisterTypes方法)。
因此,您必须在构造函数中显式地命名它。另外,每个How to configure Unity to inject an array for IEnumerable都需要一个数组来获取所有已注册的ILoader类型。
public MainCls([Dependency("Conf")] IConf conf, ILoader[] loaders)当然,使用命名依赖项也有一些缺点(例如,如果重构和重命名类会发生什么情况)。看看With Unity how do I inject a named dependency into a constructor?的第二个答案,看看使用工厂模式的策略。
https://stackoverflow.com/questions/59334237
复制相似问题