且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SimpleServiceLocator:为什么单例不支持自动构造函数注入?

更新时间:2023-11-13 13:58:16

RegisterSingle< T> 方法只是一种花哨的助手方法,目的是使生活更轻松。使用 RegisterSingle< T> 可以执行的操作也可以通过 Register< T> 方法完成。 网站提供了此示例。您可以使用 Register< T> 方法注册一个实例,如下所示(它使用闭包):

The RegisterSingle<T> method is just a fancy helper method just to make life easier. What you can do with RegisterSingle<T> can also be done with the Register<T> method. The web site gives examples of this. You can register a single instance using the Register<T> method as follows (it uses a closure):

var weapon = new Katana();
container.Register<IWeapon>(() => weapon);

当您查看生活方式管理示例,您可以看到以下创建线程静态实例的示例:

When you look at the lifestyle management examples on the web site, you can see the following example for creating a thread static instance:

[ThreadStatic]
private static IWeapon weapon;

container.Register<IWeapon>(
    () => return weapon ?? (weapon = new Katana()));

我认为这是简化的力量,因为您几乎无法做任何事情模式。您必须尝试实现的目标要困难一些,我必须承认这一点,但是没有真正先进的IMO。这是解决问题所需的代码:

I think this is the power of simplify, because there is almost nothing you can't do with this pattern. What you are trying to achieve is a bit harder, I must admit this, but nothing really advanced IMO. Here is the code you need to solve your problem:

private static IWeapon weapon;

container.Register<IWeapon>(
    () => weapon ?? (weapon = container.GetInstance<Katana>()));

技巧是将实例存储在一个静态变量中(就像使用线程static一样),但是现在您不应该通过 new 自己创建实例,而是将创建委托给Simple Service Locator。之所以行之有效,是因为–如您所知–当请求具体类型时,SimpleServiceLocator会自动进行构造函数注入。

The trick is here to store the instance in a static variable (just as with the thread static), but now you should not create the instance yourself by newing it up, but you delegate the creation to the Simple Service Locator. This works, because –as you know- the SimpleServiceLocator will do automatic constructor injection when a concrete type is requested.

我必须承认这是我们需要的耻辱做这个骗术。如果图书馆可以真正为我们做到这一点,那就太好了。例如,我可以想象添加了 RegisterSingle< T> 重载,这使我们可以执行以下操作:

I must admit that it is a shame that we need to do this trickery. It would be nice if the library could actually do this for us. For instance, I can imagine a RegisterSingle<T> overload being added that allows us to do the following:

container.RegisterSingle<IWeapon>(
    () => container.GetInstance<Katana>());

请告诉我您对这种超载的看法。我一直对反馈有兴趣,以使图书馆变得更好。

Please let me know what you think of such an overload. I'm always interested in feedback to make the library better. This would certainly be a nice feature for the next release.

更新:

自0.14版以来,我们可以

Since release 0.14 we can do the following:

container.RegisterSingle<IWeapon, Katana>();

再简单不过了。

欢呼