我有一个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有点陌生,我甚至不确定这是否是正确的方式,我认为这与我注册了两次有关,我不确定。
非常感谢任何建议或帮助。
您可以尝试为此使用Autofac lambda注册,并使用以下代码段(此处的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>();
然后通过将参数传递给lambda表达式来解析A
。您可以使用TypedParameter
而不是命名的(仅限常数值(或ResolvedParameter
(动态值(
var a = container.Resolve<A>(new NamedParameter("condition", true));
如果您不想显式调用Resolve
,可以查看委托工厂(例如Func<T>
(
这里有一个简单的解决方法:
你可以将类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会根据注册的内容解决问题。
我相信你已经非常接近了,你确实需要将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()));
}