Unity Container ResolutionFailedException when displaying correctly in configuration file

I used ServiceLocator , which I did DIing with Unity

 public ServiceLocator(IUserStore userStore, IProdcutsStore productsStore, ...etc) {} public IUserStore UserStore { get { return userStore; } } 

All this worked fine, but I wanted to lazily create repositories, since they are of relatively rare use.

So my ServiceLocator now looks like

  public ServiceLocator(IUnityContainer container) {} public IUserStore UserStore { get { return (IUserStore)container.Resolve(typeof(IUserStore)); } } // ...etc 

Now I get a really useless ResolutionFailedException error

Problem resolving failed, type = "DomainModel.DataServices.Interface.IUserStore", name = "". Exception message: current build operation (build key build [DomainModel.DataServices.Interface.IUserStore, null] key) failed: the current type, DomainModel.DataServices.Interface.IUserStore, is an interface and cannot be built. Are you missing the display type? (BuildPlanStrategy Strategy Type Index 3)

I inform you that my type of interface cannot be created, because this interface is pretty pointless. I know this is an interface, so the container should solve it for me!

In any case, pay attention to the fact that I know that type matching in the configuration is fine, because when I just entered the type interface directly, and did not try to lazy the load, it resolved it without any problems.

What am I missing, then something must change somewhere, so that lazy loading in this way?

Update: I guess what happens here is that when I insert the container into the ServiceLocator, the β€œmain” container creates an instance of the new container each time, which is then incorrectly configured. I think maybe I need to somehow indicate that I should pass this as a container, and not allow it with a new instance.

+4
source share
1 answer

You are going in a slightly wrong direction ... First you had a test class that declared its dependencies in the constructor, and you turned it into a non-testable class, asking for "something" inside the container ... Not good = (

You must either implement some factory interface for your expensive object, or require it in the constructor, or (if you can) switch to Unity 2.0 and use Automated factories :

 public ServiceLocator(Func<IUserStore> userStoreBuilder) //... public IUserStore UserStore { get { return userStoreBuilder(); } } 

If you only want to instantiate this object once, you can add cahcing to this property or with .NET 4.0 you can try to query Lazy in the constructor .

<s> PS Oh yes. And answering your question. =) If you still want to insert an instance of your container in another place, you first need to register it inside yourself =)

 container.RegisterInstance<IUnityContainer>(container); 

Fix (see comments) DO NOT register the Unity container inside itself, this will throw a StackOverflowException in container.Dispose() , the correct instance will be introduced as a dependency without registration.

+3
source

All Articles