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.
The 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);
.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 upsharedLib
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.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
.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)