使用Unity Application Block创建对象

时间:2014-12-15 23:36:08

标签: c# wpf dependency-injection inversion-of-control unity-container

我目前正在阅读Microsoft Unity应用程序块,以便在我的个人项目中使用它。我已经阅读了几篇关于它的文章和教程,但我对此有疑问。

this example about the framework中,他们使用Unity来创建一个继承IVehicle接口的对象。那些继承自它的3个类没有任何必须在构造函数中初始化的属性,所以一切都运行良好。

显然,在我的项目中,情况并非总是如此。我在构造函数中有一些需要属性(或字段)初始化的类。我的问题是,我将如何实现这一目标?或者是Unity本身无法做到的事情;我必须使用Unity的Resolve()函数创建对象,它会给我一个带有未初始化字段/属性的对象,然后我必须在每个字段/属性上逐个调用setter?< / p>

1 个答案:

答案 0 :(得分:2)

Unity支持自动连线,允许您解析复杂的对象图,而不仅仅是单个对象。

例如,假设你有一个实现Car的类ICar依赖于使用构造函数注入的另一个类IEngine(Car的构造函数需要一个IEngine类型的参数) )。

public interface ICar
{
    void Accelerate();
}

public interface IEngine
{
    void Accelerate();
}

public class Car: ICar
{
    private readonly IEngine _engine;
    public Car(IEngine engine)      
    {
        _engine = engine;
    }

    public void Accelerate()
    {
        _engine.Accelerate();
    }
}

public class Engine: IEngine
{       
    public Engine()     
    {       
    }

    public string Message {get; set;}

    public void Accelerate()
    {
        Console.WriteLine("Accelerating." + Message);
    }
}

然后,您将在Unity中注册如何解决ICarIEngine

var _container = new UnityContainer()   
                    .RegisterType<ICar,Car>()
                    .RegisterType<IEngine,Engine>(
                          new InjectionProperty("Message", "Hello world"));

然后当你解决ICar Unity时,能够向Engine构造函数提供Car的实例,自动连接Car在IEngine上的依赖关系。对于CarEngine可能具有的任何其他依赖项以及注册用于注入的任何属性,也是如此。

var car = _container.Resolve<Car>();
car.Accelerate();
  

Accelerating.Hello world

这种方式通过解析ICar Unity将为您提供所需的完整对象图。您可以尝试样本in this fiddle

修改

您可以使用将在运行时执行的lambda方法注册要解析的类型,例如:

public interface IFoo
{
    DateTime ResolvedTime {get; set;}
}

public class Foo: IFoo
{
    public DateTime ResolvedTime {get; set;}
}

//Can be registered using a lambda as in:
container.RegisterType<IFoo,Foo>(
             new InjectionFactory(c => new Foo{ ResolvedTime = DateTime.Now }));

您可以获得一些信息on the msdn。我还用这个lambda示例更新了上面的小提琴。