1

I'm currently reading up on the Microsoft Unity Application Block in order to use it in one of my personal project. I have read a couple of articles and tutorials about it, but I have a question about it.

In this example about the framework, they use Unity in order to create an object that inherits the IVehicle interface. Those 3 classes that do inherit from it don't have any properties that have to be initialized in the constructor, so everything works well.

Obviously, in my project, this won't always be the case. I'll have some classes that do need property (or field) initialization in the constructor. My question is, how would I achieve that? Or is that something Unity can't do by itself; I would have to create the object using Unity's Resolve() function that would give me an object with uninitialized fields/properties, and then I would have to call the setter one by one on each fields/properties?

1 Answer 1

2

Unity supports auto-wiring which allows you to resolve complex object graphs and not just individual objects.

For example, let´s say that you have a class Car implementing ICar that depends on another class IEngine using constructor injection (Car´s constructor requires a parameter of type 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);
    }
}

You will then register in Unity how to resolve ICar and IEngine:

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

Then when you resolve ICar Unity will be able to provide an instance of Engine to the Car constructor, auto-wiring the dependency that Car has on IEngine. This is also true for any additional dependencies that Car or Engine may have and any properties registered for injection.

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

Accelerating.Hello world

This way by resolving an ICar Unity will give you the full object graph needed. You can try the sample in this fiddle

EDIT

You can register a type to be resolved using a lambda method that will be executed at runtime, for example:

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 }));

You can get some info on the msdn. I have also updated the fiddle above with this lambda example.

Sign up to request clarification or add additional context in comments.

3 Comments

Your answer helped me understand better. But what happens, if say, Engine needed a Message that I could only provide later on, at resolve time, and I didn't know that Message at register time at the beginning of my application? Unity seems very limited to me in that you have to give all the parameters to the constructors, all the properties, etc, at the very beginning of your application when you register your objects. Unless I am missing something still?
You can also register a type using a lambda that will be executed at runtime. If that is not enough then you could create an abstract factory interface like ICarFactory so some class could depend on this factory and would call something like carFactory.CreateCar() instead of depending directly on ICar
Can you give an example using Unity with a lambda expression to register a type in your answer above? Or point me towards a documentation for it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.