请有人帮我解决问题。
我正在尝试添加一个SeviceImpl类的实例,该实例有两个构造函数和依赖项。
以下是我得到的内容。
在变体B中,我不明白为什么BuildUp()方法需要 当对象已经存在时检查构造函数?为什么不能这样呢 注入依赖项?
public interface IService
{
void Run();
}
public class Database
{
}
public class ServiceImpl : IService
{
public ServiceImpl(int i)
{}
public ServiceImpl(bool b)
{ }
[Dependency]
public Database Db { get; set; }
public void Run()
{}
}
public static void Main()
{
using (var unity = new UnityContainer())
{
unity.RegisterInstance<Database>(new Database());
// Now I want to register an instance of ServiceImpl
// Variant A
unity.RegisterInstance<IService>(new ServiceImpl(3));
var srv = unity.Resolve<IService>();
// srv.Db is null which is bad
unity.BuildUp(srv); // Doesn't throw an exception
// srv.Db is still null
// Variant B
var srv = new ServiceImpl(3);
// Hoping this call will inject Database
unity.BuildUp(srv); // Now it does: InvalidOperationException - The type ServiceImpl has multiple constructors of length 1. Unable to disambiguate.
unity.RegisterInstance<IService>(srv);
}
}
答案 0 :(得分:1)
在变体A中,您正在注册现有实例,因此容器不会尝试注入任何其他依赖项。
在变体B中,容器创建一个委托来创建实例并注入依赖项。此委托用于创建新实例或在新实例上注入依赖项,因此如果容器无法弄清楚如何创建实例,则它将失败。您可以争辩说,如果容器用于创建实例但仍允许构建而不是无法创建委托,则容器应该设置委托,但这就是它今天的工作方式。
您可以通过使用特定构造函数注册类型来创建实例来解决此问题,但如果您不希望容器创建此类型的新实例,那么这可能不合适,只是为了构建现有实例。
unity.RegisterType<ServiceImpl>(new InjectionConstructor(false));
答案 1 :(得分:-1)
@ fsimonazzi的方法有效,但团结会调用CreatePlan
:
IBuildPlanPolicy CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey)
在RegisterType
之后。这是一个繁重的操作。