2

有人可以帮我解决这个问题吗?

我正在尝试添加具有两个构造函数和依赖项的类 SeviceImpl 的实例。

下面是我得到的。

  • 在变体 A 中,统一不会注入依赖关系。我以为会的。
  • 在 Variant BI 中,不明白为什么 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);
            }
     }
    
4

2 回答 2

1

在变体 A 中,您正在注册一个现有实例,因此容器不会尝试注入任何额外的依赖项。

在变体 B 中,容器创建一个委托来创建一个实例并注入依赖项。此委托用于创建新实例或在新实例上注入依赖项,因此如果容器无法确定如何创建实例,它将失败。您可能会争辩说,如果容器用于创建实例,则应将委托设置为 throw,但仍允许构建而不是无法创建委托,但这就是今天的工作方式。

您可以通过注册类型以使用特定构造函数创建实例来解决此问题,但如果您不希望容器创建此类型的新实例,而只是构建现有实例,则这可能不合适。

unity.RegisterType<ServiceImpl>(new InjectionConstructor(false));
于 2012-10-26T12:58:12.373 回答
-1

@fsimonazzi 的方法有效,但统一会调用CreatePlan

IBuildPlanPolicy CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey)

之后RegisterType。这是一个繁重的操作。

于 2015-03-31T13:34:11.383 回答