可能的 GetObjectsOfType 替换
我有这么一小段代码,
var idObjects = Spring.Context.Support.ContextRegistry.GetContext()
.GetObjectsOfType(typeof (ICustomInterfaceThatDoesSomething));
foreach (ICustomInterfaceThatDoesSomething icitds in idObjects.Values)
icitds.DoSomething();
有没有一种方法可以通过让 spring.net 自动将单例注入到我声明的属性(例如 ICustomInterfaceThatDoesSomething
数组)中来避免这种情况?
我想要这样的唯一原因是因为我想消除对项目的 .dll 依赖,这是单点使用。
I have this small piece of code
var idObjects = Spring.Context.Support.ContextRegistry.GetContext()
.GetObjectsOfType(typeof (ICustomInterfaceThatDoesSomething));
foreach (ICustomInterfaceThatDoesSomething icitds in idObjects.Values)
icitds.DoSomething();
Is there a way i can avoid this by having spring.net automatically inject the singletons to a property i declare, like an array of ICustomInterfaceThatDoesSomething
?
The only reason i want something like this is because i want to kill the .dll dependency on the project and this is the single point of usage.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您还可以使用方法注入:
在sharedLib中:
在Web应用程序中添加一个实现
GetAllImplementers()
的类:并在Web应用程序的对象定义中配置方法注入:
我确实认为使用
CommonServiceLocator<会更好/code> (因为服务定位就是您正在做的事情),但是以这种方式使用方法注入,您不需要引入对
SharedLib
的额外引用。You could also use method injection:
In sharedLib:
In the web app add a class that implements
GetAllImplementers()
:And configure method injection in you web app's object definitions:
I do feel that it would be better to use the
CommonServiceLocator
(since service location is what you're doing), but using method injection this way, you don't need to introduce an additional reference toSharedLib
.对我来说,您的问题有趣的部分是:如何在您的库中使用服务定位器函数(例如 spring.net 的 IApplicationContext.GetObjectsOfType(...)),而不引入对特定对象的依赖国际奥委会容器。
正如问题中所述,这很有用,因为我们希望构建不强迫使用者使用特定 IoC 容器的库。然而,我们仍然希望使用 IoC 容器,因为它简化了我们库的开发。 Jeremy Miller 在帖子 “是时候让 IoC 容器缓和了”。
他的博客文章催生了一个 codeplex 上名为 CommonServiceLocator 的小项目。该项目指定了一个用于服务定位的 IServiceLocator 接口,该接口由许多实现流行的 IoC 容器,包括 Spring.NET。
IServiceLocator
定义了IEnumerable。 GetAllInstances();
方法,这基本上就是您的问题所要求的。当您的库需要服务定位器功能时,您可以依赖 CommonServiceLocator 库,并且您和其他使用者可以使用您选择的 IoC 容器将其连接起来。
你猜怎么着:Spring.NET 适配器实现了
IEnumerable;使用 ();
。GetObjectsOfType(serviceType);
获取 AllInstancesThe interesting part of your question to me is: how to use service locator functions (such as spring.net's
IApplicationContext.GetObjectsOfType(...)
) from within your library, without introducing a dependency on a specific IoC container.As stated in the question, this is useful, because we want to build libraries that do not force the consumer to use a specific IoC container. However, we still want to use an IoC container, because it eases the development of our library. This dilemma is nicely described by Jeremy Miller in the post "It’s time for IoC Container Detente".
His blog post has led to a small project on codeplex called CommonServiceLocator. This project specifies an IServiceLocator interface for service location, that is implemented by many popular IoC containers, including Spring.NET.
The
IServiceLocator
defines aIEnumerable<TService> GetAllInstances<TService>();
method, which basically is what is asked for in your question.When your library needs service locator functionality, you can take a dependency on the CommonServiceLocator library and you and other consumers can wire it up using your IoC container of choice.
And guess what: Spring.NET adapter implements
IEnumerable<TService> GetAllInstances<TService>();
usingGetObjectsOfType(serviceType);
.我会将此答案留在这里以供将来参考,但我喜欢我的其他答案 更好。
原始答案相当长,并且非常具体于问题中的示例。
我认为不存在与
GetObjectsOfType(...)
等效的配置。然而,摆脱 Spring.net 依赖不是很容易吗?
让我看看我的理解是否正确:
我们希望摆脱最后一个依赖项,因为我们希望能够与另一个 DI 容器结合使用
sharedLib
。在sharedLib
中,我们有一个类需要向所有ICustomInterfaceThatDoesSomething
实现发出信号以执行某些操作。为此,我将创建:
MySomethingManager
用于包含 Spring 依赖项,但现在它是 Spring Free 的。现在,在连接
sharedLib
与MySomethingManager
时,我有两个选择:MySomethingManager.SomethingDoers
上使用List的属性注入;
IMySomethingDoerProvider
实现的构造函数注入两者都可以使用 Spring 和许多其他 DI 容器来完成。您可以使用第一种方法
如果您不介意在配置中列出所有
ICustomInterfaceThatDoesSomething
。如果您想要神奇的
GetObjectsOfType(...)
代码,您可以使用 DI 容器的功能来创建IMySomethingDoerProvider
。使用 Spring 时,第二种方法需要创建:
您可以将其放置在依赖于
sharedLib
的项目中。由于您的webApp
已经依赖于 Spring.Core,因此您可以将MyProvider
放在那里以帮助您快速入门。注释
如果每个实例调用一次
DoSomething
,您可能会考虑指定一个初始化方法。I'll leave this answer here for future reference, but I like my other answer better.
The original answer is rather lenghty and very specific to the example in the question.
I don't think there is a configuration equivalent to
GetObjectsOfType(...)
.However, isn't it very easy to get rid of the Spring.net dependency?
Let me see if I understand correctly:
We want to get rid of the last dependency, because we want to be able to use
sharedLib
in combination with another DI container. InsharedLib
we have a class that needs to signal allICustomInterfaceThatDoesSomething
implementations to do something.For this purpose I'd create:
MySomethingManager
used to contain the Spring dependency, but now it's Spring Free.Now I have two options when wiring up
sharedLib
with regard toMySomethingManager
:MySomethingManager.SomethingDoers
with aList<ICustomInterfaceThatDoesSomething>
IMySomethingDoerProvider
implementationBoth can be done using Spring and many other DI containers. You can use the first approach
if you don't mind listing all
ICustomInterfaceThatDoesSomething
in the configuration.If you want magical
GetObjectsOfType(...)
code, you can use the features of your DI container to create aIMySomethingDoerProvider
.When using Spring, the second approach would require to create:
Which you can place in a project that depends on
sharedLib
. Since yourwebApp
already depends on Spring.Core, you could placeMyProvider
there to get you started quickly.Notes
If
DoSomething
is called once per instance, you might consider specifying an initialization method instead.感谢 Marijin 的洞察力,这已经解决了!
首先考虑这个通用实用程序类,
使用此配置示例对其进行声明
,最后注入到所需的目标。
这种方法的真正优点在于,在实际执行之前不会调用底层的 GetObjectsOfType
GetAllICheImplentations()
(除非您尝试在 spring init 期间执行它,这不是一个好兆头)thanx to Marijin's insight this has been nailed!
Firstly consider this all-purpose utility class
declare it with this configuration sample
and finally inject to the required target
What is trully great with this methodology is that the underlying GetObjectsOfType is not going to be called until you actually execute
GetAllICheImplentations()
(unless you try to execute it during spring init which is not going to bode well)