使用Unity使用额外参数创建对象

时间:2009-10-02 13:16:17

标签: c# .net unity-container prism

我正在使用Prism,它也是很好的Unity IoC容器。我是这个概念的新手,所以我还没有全力以赴。我现在要做的是使用IoC容器创建一个对象,但也传递一个额外的参数。请允许我用一个例子来解释..:

我有一个接受命令对象的类。这是在IoC容器中注册的,因此它可以很好地处理它:

public class Person 
{
    public Person(IApplicationCommands commands) { .. }
    ..
}

Person person = _container.Resolve<Person>();

现在 - 我想传递另一个论点 - 例如这个人的名字。但是,我仍然希望使用IoC容器来处理解析,从而从IoC容器中获取其他参数。但是将名称作为“自定义”参数传递。可以这样做吗?

public class Person 
{
    public Person(IApplicationCommands commands, string name) { .. }
    ..
}

string name = "John"; 
Person person = _container.Resolve<Person>(name); // ....?? 

这个例子似乎不起作用,但有没有办法使它工作?或者Unity IoC容器是否要求在调用Resolve之前在容器中注册所有参数?

4 个答案:

答案 0 :(得分:18)

Can I pass constructor parameters to Unity's Resolve() method?

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"

答案 1 :(得分:9)

编辑:在我看来,这个答案已经过时,因为它假设有较旧版本的Unity。 NotDan's answer更好。


你有几个选择。他们老实说有点蹩脚,但他们会工作。

选项1:Scoped Container

  

如果你想使用构造函数   注射,你需要创建一个   范围内的容器并放置您的数据   进入那个范围内的容器:

IUnityContainer subContainer = _container.CreateChildContainer();

//Don't do this... create a custom type other than string, like
// MyConstructorParams or something like that... this gets the point across.
subContainer.RegisterInstance<string>("John");
Person person = subContainer.Resolve<Person>();

选项2:初始化方法

  

我通常做的是有一个   我的分离初始化方法   实例变量的目标对象:

public class Person
{
     public Person(IApplicationCommands commands)
     { .. }
     public void Initialize(string name) { .. }

     ..
}
     

然后您的用法变为:

Person person = container.Resolve<Person>();
person.Initialize("John");

两者都不是特别令人愉快,但它会完成工作。重要的是选择一个约定并坚持下去,否则你会有点迷失。

希望这有帮助。

答案 2 :(得分:4)

您可以考虑以下几种选择:

如果您需要创建一个除了提供的任何数据(例如客户名称)之外还具有合法依赖关系的新实体,请将其封装到工厂中,该工厂本身已注入调用对象:

Person person = _personFactory.CreatePerson("bubba");

可以向工厂注入实体的依赖项,并在需要时提供给构造函数,或者通过其他方式设置(如果可选):

var person = new Person("bubba", _domainService);

对于瞬态变量依赖项,例如特定方法使用的策略,请使用Double Dispatch:

public class Person
{
    public void DoSomethingWith(SomeStrategy strategy)
    {
        strategy.DoSomething(this);
    }
 }

答案 3 :(得分:0)

我无法想到使用构造函数注入的任何方法。我认为您需要使用property injection作为依赖项(使用Dependency属性标记),然后只接受构造函数中的字符串,自己实例化,然后使用BuildUp连接依赖项,或者使字符串成为您在Resolve后手动设置的属性。