Autofac - 动态解析带有参数的组件

发布于 2024-09-12 17:17:52 字数 887 浏览 1 评论 0原文

我有一个类,它采用接口作为构造函数参数。该接口有两种实现,我想根据变量决定在运行时使用哪种实现。

问题是上面的类位于由 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>();
    }
}

有什么想法吗?

更新:

澄清一下,这是一个现有的对象层次结构,由运行良好的现有应用程序使用。此外,对象模型比本示例中显示的模型大得多。因此,我真的不想将工厂传递给对象图中的每个构造函数,以供该图中深层的类使用。

有没有办法让 IInterface1 的不同实现传递到 Class1 而 Class2 对此一无所知?

谢谢

I have a class that takes an interface as a constructor argument. There are two implementations of this interface and I want to decide what implementation to use at runtime based on a variable.

The problem is that the class above is deep in an object heirarchy that is resolved by Autofac and so I can't pass in the argument.

Somehing like below is what I am trying to achieve.

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>();
    }
}

Any ideas?

UPDATE:

To clarify, this is an existing object hierarchy that is used by existing applications that work fine. Also, the object model is much larger than the one shown in this example. As a result I don't really want to have to pass down a factory to each constructor in the object graph to be used by a class deep in that graph.

Is there a way of getting a different implementation of IInterface1 passed into Class1 without Class2 knowing anything about it?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鸢与 2024-09-19 17:17:52

是的,注入一个隐藏类型选择方式的工厂:

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 的不同实现。您的示例有点令人困惑,因为您显示了两个实现不同接口的类。

Yes, inject a factory that hides how the types are chosen:

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);
   }
}

And then the container setup, something along these lines:

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>();

You can now use Class3 like this:

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

NOTE: I have assumed that you meant that Class2 should be injected with varying implementations of the same interface IInterface1. Your sample is a bit confusing since you are showing two classes that implements different interfaces.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文