StructureMap Registry DSL for static factory class
I'm trying to figure out if it's possible to represent the following using the StructureMap registry DSL...
I want to have StructureMap inject a ILog<T> into classes for me. I've seen examples of doing the following:
For(typeof(ILog<>)).Use(typeof(Log<>));
However, I have a static factory class that creates my ILog<T> instances, like this:
开发者_开发问答LogFactory.CreateLog<T>();
Is there a way to wire this up in the StructureMap's Registry DSL?
Any help would be greatly appreciated!
I've found a way to get it to work, but its definitely not straightforward:
[Test]
public void create_open_generic_using_static_factory()
{
var container = new Container(x => x.For(typeof (ILog<>))
.EnrichWith(createWithFactory)
.Use(typeof (DummyLog<>)));
var instance = container.GetInstance<ILog<int>>();
instance.ShouldBeOfType<Log<int>>();
var instance2 = container.GetInstance<ILog<string>>();
instance2.ShouldBeOfType<Log<string>>();
}
private static object createWithFactory(object dummyInstance)
{
var closingType = dummyInstance.GetType().GetGenericArguments()[0];
var openCreateLog = typeof(LogFactory).GetMethod("CreateLog");
var closedCreateLog = openCreateLog.MakeGenericMethod(closingType);
return closedCreateLog.Invoke(null, null);
}
public static class LogFactory
{
public static ILog<T> CreateLog<T>()
{
return new Log<T>();
}
}
public interface ILog<T> { }
public class Log<T> : ILog<T> { }
public class DummyLog<T> : ILog<T>{}
Note the use of DummyLog<>
. That is just to trick StructureMap into thinking there is a default instance - it will never actually be returned from the container because it is replaced by the result of the createWithFactory
method.
Things would definitely be simpler if you could get rid of the factory method and put the logic into an enrichment/interceptor/OnCreation clause in your StructureMap registration.
AFAIK you can't do this. IOC containers are all about supplying instances, and static classes aren't instances.
I would recommend wrapping your static call in a class that implements ILog.
精彩评论