user7128918
user7128918

Reputation:

Unity and UnityContainer

I have many projects :

Service.DataAccess have a reference to Service.DataAccess.Interfaces.

Service.Main have a reference to Service.DataAccess.Interfaces and to Service.Factory

In Service.Main I have :

var instance = Service.Factory.ObjectFactory.Resolve<Service.DataAccess.Interfaces.IDataAccessLayer>();

In Service.Factory :

public void InitContainer(IUnityContainer container)
{
    var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    section.Configure(container); //Exception here!
}

In my configuration file :

<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
        <register type="Service.DataAccess.Interfaces.IDataAccessLayer, Service.DataAccess.Interfaces"
                  mapTo="Service.DataAccess.DataAccessLayer, Service.DataAccess" />
    </container>
</unity>

But I have a exception at runtime in InitContainer method :

The type name or alias Service.DataAccess.Interfaces.IDataAccessLayer could not be resolved. Please check your configuration file and verify this type name.

I don't understand

Thank's!

Upvotes: 0

Views: 230

Answers (1)

smoksnes
smoksnes

Reputation: 10851

Your container need to be able to access the constructor of your implementation. So it needs access to a public constructor of the class Service.DataAccess.DataAccessLayer, which means that your Service.Factory needs to reference Service.DataAccess. But also Service.DataAccess.Interfaces, because otherwise it will not find the interface.

You may also separate it into several steps, and let each library take care of their own registrations.

Main doesn't necessarily need have a reference to Service.DataAccess if it goes through Service.Factory to create it. Let's take a very simple example.

In your Main:

var container = new UnityContainer();
container.Register<IFactory, SomeFactory>(); // Factory is a class in Service.Factory.

// Let your factory project take care of it's registrations as well.
Service.Factory.Startup.InitContainer(container);

var factory = container.Resolve<IFactory>();
Service.DataAccess.Interfaces.IDataInterface foo = factory.Create(); 

In your Service.Factory:

// Class for initiating registrations.
public static class Startup
{
    public static InitContainer(IUnityContainer container)
    {
        var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
        section.Configure(container);
    }
}

// Some example class...
public class SomeFactory : IFactory
{
    private readonly IUnityContainer _container;

    public SomeFactory(IUnityContainer container)
    {
        _container = container;
    }

    public IDataInterface Create()
    {
        // return the implementation.
        return _container.Resolve<IDataInterface>();
    }
}

Note that the SomeFactory uses the ServiceLocator anti-pattern. But it's mostly a proof-of-concept to show how it could work. It's a way to let Service.Main only reference the interfaces, but not the concrete classes. Service.Factory, however, needs to reference both.

Upvotes: 1

Related Questions