c# - Unity 多接口实现按约定注册
问题描述
我正在尝试按照惯例注册单个接口的多个实现,然后将所有这些接口用作其他类中的依赖项。不幸的是,我在尝试这样做时遇到了一些问题。
我想注册多个实现,所以我添加了WithName.TypeName
druing 注册,但这似乎引起了问题。没有它,我无法为单个接口注册多个实现。
以下是不起作用的简单示例。Unity 抛出异常,我不知道为什么。
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();
}
}
}
解决方案
问题是您正在使用该WithName.TypeName
选项。这意味着程序集中的每种类型都是作为容器中的命名注册完成的。在您的情况下这是一件好事,因为您正在注册多个ILoader
实例,因此容器必须能够区分它们。但是,这也意味着当它被解析时,您必须传递名称才能让容器找到它。
换句话说,当容器看到构造函数时public MainCls(IConf conf, IEnumerable<ILoader> loaders)
,它会将其解释为“IConf
使用默认名称注入实例”,这在您的容器中不存在。您IConf
的注册名称为“Conf”(或者可能是“KYPClient.Conf”,我不确定,因为我从未使用过该RegisterTypes
方法)。
因此,您必须在构造函数中明确命名它。此外,根据如何配置 Unity 为 IEnumerable 注入数组,您需要一个数组来获取所有已注册的ILoader
类型。
public MainCls([Dependency("Conf")] IConf conf, ILoader[] loaders)
当然,使用命名依赖项有一些缺点(例如,如果重构和重命名类会发生什么情况)。看看With Unity 如何将命名依赖项注入构造函数的第二个答案?使用工厂模式的策略。
推荐阅读
- tensorflow.js - 安装 tensorflow/tfjs-node 时出现 sysmlink 错误
- postgresql - 递归 CTE 血统(拥有多个经理的员工)
- docker - docker eclipse-mosquitto:2.0.7 错误:地址不可用
- c# - 从 ASP.NET Core 页面将 HTML 表单提交到 PHP 文件
- php - 将 MySQL 结果查询到多维关联 PHP 数组中
- azure - Azure WAG(Web 应用程序网关)背后的 KeyClock 设置
- r - Transmute 有效,但 mutate 无效
- asp.net-core - 用户登录后如何在 Blazor 服务器端应用程序中获取 AD B2C 用户的 GROUP?
- laravel - belongsTo 的包装器返回 null
- flutter - 有没有办法调用 Flutter Web 平台原生代码?