开发者

How to register a named type mapping to resolve to the unnamed type mapping

I am using entity framework with the unit of work design pattern, my class structure is as follows:

public interface IUnitOfWork
{
    void Save();
}

public class MyContext : ObjectContext, IUnitOfWork
{
    public void Save()
    {
        SaveChanges();
    }
}

I then register the MyContext type mapping as:

IUnityContainer unityContainer = new UnityContainer()
    .RegisterType<MyContext>(new ContainerControlledLifetimeManager());

I know if I did the following:

unityContainer.RegisterType<IUnitOfWork, MyContext>();
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>();
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>();

Then unitOfWork1 would be the same MyContext instance as unitOfWork2, as IUnitOfWork maps to MyContext, which is a container controlled instance.

However, if instead I do this:

unityContainer.RegisterType<IUnitOfWork, MyContext>("MyUnitOfWork");
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");

Then unitOfWork1 and unitOfWork2 resolve to two different instances of MyContext, which doesn't make any sense to me, as they both map to MyContext, which is still a container controlled instance. It appears that when the mappings are named, they don't resolve the second type parameter in the s开发者_开发技巧ame way.

The reason I require named type mappings is because I have multiple different ObjectContexts all of which implement IUnitOfWork, so it would be wrong to define a global IUnitOfWork type mapping.

My question is simply, how can I use named type mappings but still retain the functionality of the first implementation.

N.B. I am actually using a PerResolveLifetimeManager in my real implementation, however ContainerControlledLifetimeManager highlights the point in less code.

Edit

As per my conversation with Daniel Hilgarth.

I fixed my problem by changing the registration of the class with a dependency property of IUnitOfWork.

Previously it was along the lines of:

unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("MyUnitOfWork")));

However, instead of resolving a named IUnitOfWork, I took a different approach and instead resolved the implementation directly:

unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<MyContext>()));

Thank you Daniel and TheCodeKing for explaining the purpose of named registrations :)


Simply pass the lifetime manager:

unityContainer.RegisterType<IUnitOfWork, MyContext>(
    "MyUnitOfWork", new ContainerControlledLifetimeManager());

Reason:
You registered the unnamed instance of MyContext as a container controlled instance, not the named one.


The ContainerControlledLifetimeManager enforces a singleton so you always get the same instance. To use named instances which resolve a singleton, you need.

unityContainer.RegisterType<IUnitOfWork, MyContext>
                     ("MyUnitOfWork", new ContainerControlledLifetimeManager());
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜