2010-08-04 74 views
4

我有一个接口作为构造函数参数的类。这个接口有两个实现,我想根据变量来决定在运行时使用什么实现。Autofac - 动态解析组件参数

问题是,上面的类是深入的对象heirarchy由Autofac解决,所以我不能传递参数。

像下面这样的兴趣是我想要实现的。

public interface IInterface1 {} 
public interface IInterface2 {} 

public class Class1 : IInterface2 
{ 
    public Class1(IInterface1 interface1) 
    { 
    } 
} 

public class Class2 
{ 
    public Class2(IInterface2 interface2) 
    { 
    } 
} 

public class Class3 
{ 
    public void GetClass2Instance(string interface1ImplementationToChoose) 
    { 
     // want to change which implementation of IInterface1 is resolved based on the interface1ImplementationToChoose variable 
     var class2 = container.Resolve<Class2>(); 
    } 
} 

任何想法?

UPDATE:

为了澄清,这是用于由工作正常现有应用程序的现有对象分层结构。而且,对象模型比本例中显示的要大得多。因此,我并不想将工厂传递给对象图中的每个构造函数,以供图中深层的类使用。

有没有办法让IInterface1的不同实现传入Class1,而Class2不知道任何事情呢?

感谢

+0

你说“这个接口有两种实现..”,但你的示例并没有很好地显示出来。你能否详细说明,然后我会相应地更新我的答案。 – 2010-08-05 10:25:27

回答

6

是,注入一个工厂,隐藏了怎样的类型选择:

public class Class3 
{ 
    private Func<string, Class2> _class2Factory; 
    public Class3(Func<string, Class2> class2Factory) 
    { 
     _class2Factory = class2Factory; 
    } 

    public void GetClass2Instance(string interface1ImplementationToChoose) 
    { 
     var class2 = _class2Factory(interface1ImplementationToChoose); 
    } 
} 

然后在容器设置,东西沿着这些线路:

builder.RegisterType<Implementation1>().Named("imp1").As<IInterface1>(); 
builder.RegisterType<Implementation2>().Named("imp2").As<IInterface1>(); 
builder.Register<Func<string, Class2>>(c => 
    { 
     var context = c.Resolve<IComponentContext>(); 
     return imp => new Class2(context.Resolve<IInterface1>(imp)); 
    }); 
builder.RegisterType<Class3>(); 

您现在可以使用Class3这样的:

public class Class4 
{ 
    public Class4(Class3 class3) 
    { 
     var class2with1 = class3.GetClass2Instance("imp1"); 
     var class2with2 = class3.GetClass2Instance("imp2"); 
    } 
} 

注意:我假设你的意思是Class2应注入不同的实现相同的接口IInterface1。你的示例有点混乱,因为你显示了两个实现不同接口的类。

+0

看起来不错;另外,c =>新的Class2(context.Resolve (imp))就足够了(除非你打算保留一个引用,否则你不需要明确地解析IComponentContext。) – 2010-08-05 22:30:45

+0

我不仅在'Class2' ,在这种情况下,我正在注册一个'Func '委托,它必须携带它自己的上下文。对? – 2010-08-06 08:14:47

+0

@Nicholas - 我忘记了我应该为注册调用指定委托类型,或许现在更有意义。我仍然觉得我不得不解决一个新的上下文来在lambda中“存储”... – 2010-08-06 10:02:41