带参数的 Unity 自动工厂
我正在尝试找出注入带有参数的自动工厂的正确方法,或者即使这可以通过 Unity 实现。
例如,我知道我可以这样做:
public class TestLog
{
private Func<ILog> logFactory;
public TestLog(Func<ILog> logFactory)
{
this.logFactory = logFactory;
}
public ILog CreateLog()
{
return logFactory();
}
}
Container.RegisterType<ILog, Log>();
TestLog test = Container.Resolve<TestLog>();
ILog log = test.CreateLog();
现在我希望能够做的是:
public class TestLog
{
private Func<string, ILog> logFactory;
public TestLog(Func<string, ILog> logFactory)
{
this.logFactory = logFactory;
}
public ILog CreateLog(string name)
{
return logFactory(name);
}
}
Container.RegisterType<ILog, Log>();
TestLog test = Container.Resolve<TestLog>();
ILog log = test.CreateLog("Test Name");
不幸的是,这不起作用。我可以看到如何设置自定义工厂来在 Unity 中创建实例,但似乎无法为该示例提供任何明确的示例。
显然我可以创建自己的工厂,但我正在寻找一种优雅的方法来在 Unity 中以最少的代码实现此目的。
I'm trying to figure out the correct way to inject an auto-factory which takes params, or even if this is possible with Unity.
For example I know I can do this:
public class TestLog
{
private Func<ILog> logFactory;
public TestLog(Func<ILog> logFactory)
{
this.logFactory = logFactory;
}
public ILog CreateLog()
{
return logFactory();
}
}
Container.RegisterType<ILog, Log>();
TestLog test = Container.Resolve<TestLog>();
ILog log = test.CreateLog();
Now what I'll like to be able to do is:
public class TestLog
{
private Func<string, ILog> logFactory;
public TestLog(Func<string, ILog> logFactory)
{
this.logFactory = logFactory;
}
public ILog CreateLog(string name)
{
return logFactory(name);
}
}
Container.RegisterType<ILog, Log>();
TestLog test = Container.Resolve<TestLog>();
ILog log = test.CreateLog("Test Name");
Unfortunately this doesn't work. I can see how you can set up custom factories for creating instances in Unity, just can't seem to fund any clear examples for this example.
Obviously I could create my own factory but I'm looking for an elegant way to do this in Unity and with minimum code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
很抱歉成为那些自己回答问题的烦人之一,但我想通了。
Sorry to be one of those annoying people who answer their own questions but I figured it out.
@TheCodeKing 的答案工作正常,但在大多数(可能是所有?)情况下可以缩短为以下内容:
(请注意,我使用的是
RegisterInstance()
而不是RegisterType ()
)由于
Func<>
实现已经是一种工厂,因此通常不需要将其包装在InjectionFactory
中。它仅确保Func
的每个解析都是一个新实例,我真的无法想到需要此的场景。The answer by @TheCodeKing works fine, but in most (possibly all?) cases could be shortened to the following:
(note that I'm using
RegisterInstance()
instead ofRegisterType()
)Since the
Func<>
implementation is already a kind of factory there's usually no need to wrap it in aInjectionFactory
. It only ensures that each resolution of theFunc<string, ILog>
is a new instance, and I can't really think of a scenario that requires this.Autofac 具有 参数化实例化来处理需要带参数的自动工厂的场景。
虽然 Unity 不支持开箱即用,但可以实现一个可以在类似于 Autofac 的方式。
一个无耻的插件:我实现了这样一个扩展——参数化汽车工厂。
它的使用方式与此类似:
请注意:
Func
是从container
解析的,但它没有在任何地方注册 - 它是生成的自动地。Func
仅向LogConsumer
的构造函数提供string ConsumerName
参数。结果,Log log
参数从容器中解析出来。如果自动工厂函数看起来像这样Func
,那么LogConsumer
构造函数的所有参数都将通过 auto 提供-工厂。基本上,该扩展的工作原理如下:
Func
,则扩展会拦截实例构建过程。Func
,该函数从容器解析其返回类型,并将Func
的参数作为ResolverOverride 集合到
IUnityContainer.Resolve
方法。Autofac has parameterized instantiation to handle scenarios which need an auto-factory with parameters.
While Unity doesn't support this out of the box, it's possible to implement an extension which will work in a way similar to Autofac's.
A shameless plug: I implemented such an extension -- Parameterized Auto Factory.
It can be used in a way similar to this:
Please notice:
Func<string, LogConsumer>
is resolved fromcontainer
, but it wasn't registered anywhere -- it's generated automatically.Func<string, LogConsumer>
only provides thestring consumerName
parameter toLogConsumer
's constructor. As a result, theLog log
parameter is resolved from the container. If the auto-factory func looked like thisFunc<string, Log, LogConsumer>
instead, then all the parameters ofLogConsumer
's constructor would've been supplied through the auto-factory.Basically, the extension works like this:
BuilderStrategy
in Unity's pipeline.Func
with parameters, the extension intercepts the instance building process.Func
of the given type which resolves its return type from the container and passes theFunc
's parameters as aResolverOverride
collection to theIUnityContainer.Resolve
method.如果您正在寻找完全类型化的工厂接口(例如,允许 XML 文档和参数名称),您可以使用 NuGet 包,您只需为工厂定义一个接口,然后将其与您想要的具体类型相关联即可利用它实例化。
代码位于 GitHub 中:https://github.com/PombeirP/FactoryGenerator
In case you're looking for a fully typed factory interface (allowing for XML documentation and parameter names, for instance), you could use a NuGet package I created, which you can leverage simply by defining an interface for the factory, and then associating it with the concrete type you want to instantiate.
Code lives in GitHub: https://github.com/PombeirP/FactoryGenerator