mat*_*i82 4 .net c# dependency-injection castle-windsor inversion-of-control
我有一个依赖于字符串的类:
public class Person
{
private readonly string _name;
public Person(string name)
{
if (name == null) throw new ArgumentNullException("name");
_name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
该字符串'name'仅在运行时才知道,例如.它在配置中定义.所以我有这个提供这个字符串的接口:
public interface IConfiguration
{
string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)
这两种类型,Person和IConfiguration(其实现在这里并不重要)都在Windsor容器中注册.
问题:如何告诉WindsorCastle容器它应该将IConfiguration的Name属性注入Person类的构造函数?
警告:我不想将IConfiguration注入Person类或使用类型化的工厂...... Person类必须简单并且只接受字符串作为参数.
可能有更多的方法可以做到这一点,因为温莎是非常灵活的,但这里有三个我的头顶:
如果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;
}
Run Code Online (Sandbox Code Playgroud)
在解析之前调用此方法Person,并将name键/值对设置为所需的值.然后,Windsor使用此字典覆盖构造函数中的任何依赖项.我可能只是让它成为一个lambda:
.DynamicParameters((k,p) => p["name"] = k.Resolve<IConfiguration>().Name));
Run Code Online (Sandbox Code Playgroud)
如果该Name值实际上是在应用程序设置文件中定义的,那么Windsor有一个内置选项:
container.Register(
Component.For<Person>()
.DependsOn(Dependency.OnAppSettingsValue("name", "configSettingKeyName")));
Run Code Online (Sandbox Code Playgroud)
你说你不想使用Typed Factories,但我认为这是一个合理的使用方法.它根本不会使Person类复杂化,但它会为创建Person对象的代码增加一点(人?).这是一个例子:
定义工厂界面:
public interface IPersonFactory
{
Person Create(string name);
}
Run Code Online (Sandbox Code Playgroud)
然后在你创建的地方Person,注入工厂并使用它:
public class PersonUser
{
public Personuser(IConfiguration configuration, IPersonFactory personFactory)
{
Person person = personFactory.Create(configuration.Name);
}
}
Run Code Online (Sandbox Code Playgroud)
您必须添加设施并注册界面,但这很容易:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IPersonFactory>().AsFactory());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1892 次 |
| 最近记录: |