c# – 如何构造函数 – 注入仅在运行时已知的字符串? (温莎城堡)
作者:互联网
我有一个依赖于字符串的类:
public class Person
{
private readonly string _name;
public Person(string name)
{
if (name == null) throw new ArgumentNullException("name");
_name = name;
}
}
该字符串’name’仅在运行时才知道,例如.它在配置中定义.所以我有这个提供这个字符串的接口:
public interface IConfiguration
{
string Name { get; }
}
这两种类型,Person和IConfiguration(其实现在这里并不重要)都在Windsor容器中注册.
问题:如何告诉WindsorCastle容器它应该将IConfiguration的Name属性注入Person类的构造函数?
警告:我不想将IConfiguration注入Person类或使用类型化的工厂…… Person类必须简单并且只接受字符串作为参数.
解决方法:
可能有更多的方法可以做到这一点,因为温莎是非常灵活的,但这里有三个我的头顶:
选项1:
如果IConfiguration是单例或以某种方式可以在没有任何其他帮助的情况下填充Name,则可以执行以下操作:
container.Register(Component.For<IConfiguration>().ImplementedBy<Configuration>());
container.Register(Component
.For<Person>()
.DynamicParameters((DynamicParametersDelegate)ResolvePersonName));
// This should be a private method in your bootstrapper
void ResolvePersonName(IKernel kernel, IDictionary parameters)
{
parameters["name"] = kernel.Resolve<IConfiguration>().Name;
}
在解析Person之前调用此方法,并将名称键/值对设置为所需的值.然后,Windsor使用此字典覆盖构造函数中的任何依赖项.我可能只是让它成为一个lambda:
.DynamicParameters((k,p) => p["name"] = k.Resolve<IConfiguration>().Name));
选项2:
如果Name值实际上是在应用程序设置文件中定义的,那么Windsor有一个内置选项:
container.Register(
Component.For<Person>()
.DependsOn(Dependency.OnAppSettingsValue("name", "configSettingKeyName")));
选项3:
你说你不想使用Typed Factories,但我认为这是一个合理的使用方法.它根本不会使Person类复杂化,但它会为创建Person对象的代码添加一些内容(人?).这是一个例子:
定义工厂界面:
public interface IPersonFactory
{
Person Create(string name);
}
然后在您创建Person的位置,注入工厂并使用它:
public class PersonUser
{
public Personuser(IConfiguration configuration, IPersonFactory personFactory)
{
Person person = personFactory.Create(configuration.Name);
}
}
您必须添加设施并注册界面,但这很容易:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IPersonFactory>().AsFactory());
标签:c,dependency-injection,net,inversion-of-control,castle-windsor 来源: https://codeday.me/bug/20190609/1206511.html