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

发布于 2024-08-07 02:33:39 字数 720 浏览 3 评论 0原文

我正在使用 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之前将所有参数注册到容器中?

I'm using Prism, which gives be the nice Unity IoC container too. I'm new to the concept, so I haven't gotten my hands all around it yet. What I want to do now is to create an object using the IoC container, but passing an extra parameter too. Allow me to explain with an example..:

I have a class that takes a commands object. This is registered in the IoC container, so it will handle it nicely:

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

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

Now - I want to pass in another argument - e.g. the name of the person. However, I still want to use the IoC container to handle the resolving and hence get the other paramenters from the IoC container. But pass in the name as a "custom" parameter. Can this be done?

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

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

This example doesn't seem to work, but is there a way to make it work? Or does Unity IoC container require all parameters to be registered in the container before calling Resolve?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风不识月 2024-08-14 02:33:39

我可以将构造函数参数传递给 Unity 的 Resolve() 方法吗?

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

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

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
沉溺在你眼里的海 2024-08-14 02:33:39

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


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

选项 1:作用域容器

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

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:初始化方法

不过,我通常做的是
我的单独的初始化方法
实例变量的目标对象:

公共类 Person
{
     公共人员(IApplicationCommands 命令)
     { .. }
     公共无效初始化(字符串名称){..}

     ..
}

然后你的用法就变成了:

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

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

希望这有帮助。

Edit: this answer is obsolete, in my opinion, because it has an assumption of an older version of Unity. NotDan's answer is better.


You've got a few options. They are honestly a bit lame, but they will work.

Option 1: Scoped Container

If you want to use constructor
injection, you'll need to create a
scoped container and put your data
into that 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>();

Option 2: Initialize Method

What I typically do, though, is have a
seperate Initialize method on my
target objects for instance variables:

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

     ..
}

And then your usage becomes:

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

Neither is particularly pleasant, but it'll get the job done. The important thing is to pick a convention and stick to it, otherwise you'll get a bit lost.

Hope this helps.

倾听心声的旋律 2024-08-14 02:33:39

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

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

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

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

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

对于瞬态变量依赖项,例如特定方法使用的策略,请使用双重派遣:

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

There are a few choices you might consider:

In the case where you need to create a new entity which has legitimate dependencies in addition to any data being supplied (e.g. customer name), encapsulate this into a factory which itself has been injected into the calling object:

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

The factory can be injected with the entity's dependencies and supplied to the constructor if required or set by other means if optional:

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

For transient-variable dependencies, such as a strategy used by a particular method, use Double Dispatch:

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

烟酉 2024-08-14 02:33:39

我想不出任何方法可以通过构造函数注入来做到这一点。我认为您需要对依赖项使用属性注入(标记有 Dependency 属性),然后只采用构造函数中的字符串,实例化自己,然后使用 BuildUp 连接依赖项,或者将字符串也设置为您在 Resolve 后手动设置的属性。

I can't think of any way to do this with constructor injection. I think you'll need to use property injection for the dependencies (marked with the Dependency attribute) and then either take just the string in the constructor, instantiate yourself, then use BuildUp to wire the dependencies, or make the string a property too that you set manually after Resolve.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文