Unity IOC Static Factories

2019-02-27 07:17发布

Is there a way via xml configuration to denote a static factory method on an object?

1条回答
你好瞎i
2楼-- · 2019-02-27 07:55

Inversion of control/dependency injection and static do not mix well. Instead, do the following. Have an IFooFactory and a concrete implementation FooFactory:

public interface IFooFactory {
    Foo Create();
}

public class FooFactory : IFooFactory {
    public Foo Create() {
        Foo foo = // create Foo
        return foo;
    }
}

Then, register FooFactory as the concrete implementation of IFooFactory with ContainerControlledLifeTimeManager so that it acts like a singleton:

IUnityContainer container = new UnityContainer();
var manager = new ContainerControlledLifeTimeManager();
container.RegisterType<IFooFactory, FooFactory>(manager);

Then, when you need the factory:

IFooFactory factory = container.Resolve<IFooFactory>();
Foo foo = factory.Create();

If you can't alter the implementation of your factory so that it doesn't have static methods then you will need to create a wrapper:

public class FooFactoryWrapper {
    public Foo Create() {
        return FooFactoryTypeWithStaticCreateMethod.Create();
    }
}

and then register

container.Register<IFooFactory, FooFactoryWrapper>();

Of course, you can register FooFactory or FooFactoryWrapper as the concrete implementation of IFooFactory in XML too. Let me know if you need help with this.

The main point is get away from static.

That said, here's how you can register a static factory in Unity:

IUnityContainer container = new UnityContainer();
container.AddNewExtension<StaticFactoryExtension>()
         .Configure<IStaticFactoryConfiguration>()
         .RegisterFactory<IFoo>(container => FooFactory.Create());
var foo = container.Resolve<IFoo>(); // uses FooFactory

I can not figure out how to set this up using XML and after poking around using Reflector I do not think that it is possible. I can not find any classes in Microsoft.Practices.Unity.StaticFactory that could handle a configuration element. You probably have to add your own handler.

查看更多
登录 后发表回答