You could also use method injection:
In sharedLib:
public class MyService
{
public void ProcessAll()
{
foreach (ICustomInterfaceThatDoesSomething icitds in GetAllImplementers())
icitds.DoSomething();
}
protected virtual IEnumerable<ICustomInterfaceThatDoesSomething> GetAllImplementers()
{
// note that the Spring dependency is gone
// you can also make this method abstract,
// or create a more useful default implementation
return new List<ICustomInterfaceThatDoesSomething>();
}
}
In the web app add a class that implements GetAllImplementers()
:
public class ServiceLocatorImplementer : IMethodReplacer
{
protected IEnumerable<ICustomInterfaceThatDoesSomething> GetAllImplementers()
{
var idObjects = Spring.Context.Support.ContextRegistry.GetContext()
.GetObjectsOfType(typeof(ICustomInterfaceThatDoesSomething));
return idObjects.Values.Cast<ICustomInterfaceThatDoesSomething>();
}
public object Implement(object target, MethodInfo method, object[] arguments)
{
return GetAllImplementers();
}
}
And configure method injection in you web app's object definitions:
<objects>
<object name="serviceLocator"
type="WebApp.ServiceLocatorImplementer, WebApp" />
<object name="service" type="SharedLib.MyService, SharedLib">
<replaced-method name="GetAllImplementers" replacer="serviceLocator" />
</object>
</objects>
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 to SharedLib
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…