SimpleServiceLocator:为什么单例不支持自动构造函数注入? [英] SimpleServiceLocator: Why is automatic constructor injection not supported for singletons?

查看:117
本文介绍了SimpleServiceLocator:为什么单例不支持自动构造函数注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试 SimpleServiceLocator ,我很喜欢它,但是有一个我真的很沮丧-您不能对单例使用自动构造函数注入。更糟的是,您甚至无法使用自动构造函数注入来实现其依赖项。您必须手动创建单例对象,所有依赖项,所有依赖项依赖项等。

I've been experimenting with the SimpleServiceLocator, and I like it quite a bit, but there's one thing that I'm really frustrated by--you can't use automatic constructor injection for singletons. To make matters worse, you can't even use automatic constructor injection for its dependencies. You have to create the singleton object, all it's dependencies, all its dependencies dependencies, etc. manually.

为什么SimpleServiceLocator是这样设计的?

Why is SimpleServiceLocator designed this way?

不是单例应该与常规实例一样,只是在首次请求实例时,该实例将被存储并重用,而不是每次都创建一个新实例?为什么SimpleServiceLocator要求在注册过程中提供一个实例,而不是仅允许在第一次请求时创建并存储该实例?

Aren't singletons supposed to be just like regular instances except that, upon the first request for an instance, that instance is stored and reused instead of a new one being created each time? Why does SimpleServiceLocator require an instance to be provided during the registration process rather than just allow the instance to be created and stored on first request?

我明白了SimpleServiceLocator的意义。是没有太多的花哨和花哨的东西,并且对于初学者来说真的很容易使用,但是似乎它的设计不正确,并且注册单例的方法应该与注册常规实例的方法相同,除了方法名称应为 RegisterSingle< T>(),而不是 Register< T>()

I get that the point of SimpleServiceLocator is to not have a lot of bells and whistles and be really easy for beginners to use, but it seems like it's just designed incorrectly, and that the method for registering a singleton should be identical to the method for registering a regular instance except that the method name should be RegisterSingle<T>() instead of Register<T>(). Is there a reason for the more complicated (and seemingly less convenient) design I'm just not getting?

同时,还有另外一个(最好是免费的)IOC容器吗?使用该功能,让我在代码中注册对象的方式类似于SimpleServiceLocator,但是否允许对单身人士进行自动构造方法注入(或至少允许对单身人士的依赖项进行自动构造方法注入)?

Meanwhile, is there another (preferably free) IOC container I can use that let's me register objects in code similarly to the SimpleServiceLocator but does allow automatic contructor injection for singletons (or at least allows automatic constructor injection for the dependencies of the singleton)?

推荐答案

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>();

再简单不过了。

欢呼

这篇关于SimpleServiceLocator:为什么单例不支持自动构造函数注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆