我有一个Xamarin.Forms
应用程序,正在使用Autofac进行DI。
所以我想要的很简单,但是我无法做一些看起来像在做的事。
因此,我有一个包含两个构造函数的类,它们两个都有一个参数,并且根据某些条件,我想解析其中一个。例如,我有一个班级A,我想要的基于条件B或C的问题应该得到解决。
例如:
public class A
{
public A(B bObject)
{...}
public A(C cObject)
{...}
}
但是我不明白该怎么做。我尝试做以下事情:
注册:
builder.RegisterType<A>().
UsingConstructor(typeof(C)).
Named<A>(nameof(C));
builder.RegisterType<A>().
UsingConstructor(typeof(B)).
Named<A>(nameof(B));
解决方法:
DiContainer.ResolveNamed<A>(nameof(B));
DiContainer.ResolveNamed<A>(nameof(C));
注意: 我已经在容器中注册了B和C,如下所示:
builder.RegisterType<B>();
builder.RegisterType<C>()
我对AutoFac有点陌生,我甚至不确定这是否是正确的方法,我认为这与我不确定两次注册有关。
任何建议或帮助都将受到赞赏。
答案 0 :(得分:0)
这是一个简单的解决方法:
您可以将B类和C类包装到另一个类中,然后在autofac中注册:
public class Wrapper {
public B BObject;
public C CObject;
}
然后您可以像这样做一点(我不知道解决该问题的正确方法,因为我目前没有IDE,但是我希望您了解我在这里做什么):
DiContainer.ResolveNamed<A>(new Wrapper(){BObject = Binstance});
另一种解决方案:
您还可以根据需要注册B或C。
如果希望使用B实例化该类,请在autofac上注册B,然后解析该类。
但是该类需要有两个构造函数。一种以B为参数,另一种以C ...
我认为Autofac将会解决,具体取决于注册的内容。
答案 1 :(得分:0)
您可以尝试使用lambda registration来实现。使用以下代码段(c
参数是IComponentContext
实例)进行注册
var builder = new ContainerBuilder();
builder.Register(
(c, p) =>
{
var condition = p.Named<bool>("condition");
return condition ? new A(c.Resolve<B>()) : new A(c.Resolve<C>());
});
builder.RegisterType<B>();
builder.RegisterType<C>();
然后通过passing解析lambda表达式的参数来A
。您可以使用TypedParameter
代替命名(仅恒定值)或ResolvedParameter
(动态值)
var a = container.Resolve<A>(new NamedParameter("condition", true));
如果您不想显式调用Resolve
,则可以查看委托人factories(例如Func<T>
)
答案 2 :(得分:0)
我相信您非常亲密,您实际上需要将Parameter
定义传递给Resolve
public class B { }
public class C { }
public class A
{
public A(B bObject){ Console.WriteLine("I am constructor A typeof(B)");}
public A(C cObject){ Console.WriteLine("I am constructor A typeof(C)");}
}
void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<A>().UsingConstructor(typeof(B)).Named<A>(nameof(B));
builder.RegisterType<A>().UsingConstructor(typeof(C)).Named<A>(nameof(C));
//it doesn't really matter if these are registered as you're using nameof() to identify the objects - that's essentially string
builder.RegisterType<B>();
builder.RegisterType<C>();
var container = builder.Build();
var a1 = container.ResolveNamed<A>(nameof(B), new TypedParameter(typeof(B), new B()));
var a2 = container.ResolveNamed<A>(nameof(C), new TypedParameter(typeof(C), new C()));
}