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 ObjectContext
s 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");
精彩评论