0

根据 LightInject 的文档,我们可以创建一个类型化工厂并将值传递给它,如下所示:

public class Foo : IFoo
{
   public Foo(int value)
   {
       Value = value;
   }

   public int Value { get; private set; }
}

public interface IFooFactory
{
    IFoo GetFoo(int value);
}

public class FooFactory : IFooFactory
{
    private Func<int, IFoo> createFoo;

    public FooFactory(Func<int, IFoo> createFoo)
    {
        this.createFoo = createFoo;
    }

    public IFoo GetFoo(int value)
    {
        return createFoo(value);
    }
}

我们像这样注册它:

container.Register<int, IFoo>((factory, value) => new Foo(value));
container.Register<IFooFactory, FooFactory>(new PerContainerLifetime());

我们可以这样调用 GetFoo:

var typedFooFactory = container.GetInstance<IFooFactory>();
var foo = typedFooFactory.GetFoo(42);

所以现在我的问题是:我们在注册工厂 new Foo(value) 时显式地实例化 foo。但是如果我们想在我们的 GetFoo 方法中根据值来做呢?

public IFoo GetFoo(int value)
{
    switch (value)
    {
         case 1: return new Foo(1);
         case 2: return new FooThatImplementsIFoo(2);
         case 3: return new AnotherFooThatImplementsIFoo(3);
         default: return null;
    }
}

我希望能够调用 GetFoo 并根据“值”获得正确的实现。

var typedFooFactory = container.GetInstance<IFooFactory>();
var foo = typedFooFactory.GetFoo(3); 
Assert.AreEqual(foo.GetType(),typeof(AnotherFooThatImplementsIFoo));
4

1 回答 1

2

关键是要记住,在我们工厂的 GetFoo 方法中,我们没有调用委托,而只是传递了对它的引用。调用是在我们注册工厂时(通过实例化 Foo 对象)。所以我所做的是创建一个静态工厂类,它根据“值”生成 IFoo 的实现:

container.Register<int, IFoo>((factory, value) => FooFactory.GetInstance);

我的 FooFactory 看起来像这样:

public static class FooFactory
{
    public static IFoo GetInstance(IServiceFactory serviceFactory, int value)
    {
        switch (value)
        {
            case 1:
            {
                return serviceFactory.GetInstance<Foo>();
            }
            case 2:
            {
                return serviceFactory.GetInstance<FooThatImplementsIFoo>();
            }
            case 3:
            {
                return serviceFactory.GetInstance<AnotherFooThatImplementsIFoo>();
            }
            default:
            {
                return null;
            }
        }
    }
}

所以我通过这样做来调用委托:

var typedFooFactory = container.GetInstance<IFooFactory>();
var foo = typedFooFactory.GetFoo(3); 

现在我的 foo 对象的类型是 AnotherFooThatImplementsIFoo

Assert.AreEqual(foo.GetType(),typeof(AnotherFooThatImplementsIFoo));
于 2016-07-22T21:36:58.767 回答