November Happy Hour will be moved to Thursday December 5th.

Question about IoC in Epi

Vote:
 

Okay, this might be a softball question, but this is my first jump into the IoC in Epi, so I thought I would just ask.

Say I have a service def like this:

[ServiceConfiguration(typeof(IDocumentManagementService), Lifecycle = ServiceInstanceScope.Singleton)]
public class QbankService : IDocumentManagementService

But now I am ready to reuse that interface to define another concrete class. In the places that I use that Interface, how will I tell the code to distigush WHICH implementation I want?

Do I have to have 2 seperate interfaces? Or is there a way when I'm about to either construct or service locate something concrete that I can tell it which one I want?

#194720
Jun 28, 2018 20:24
Vote:
 

  Have a look at this post from jondjones: http://www.jondjones.com/learn-episerver-cms/episerver-developers-guide/episerver-best-practices-tips-and-tricks/dependency-injection-in-episerver-servicelocator-and-injected-explained

At the bottom of that page he has an example with ServiceConfiguration and you can use it with ServiceLocator below:

var customImplmentation = ServiceLocator.Current.GetInstance<IDocumentManagementService>();

#194723
Jun 28, 2018 21:11
Vote:
 

Yeah that's a helpful article, but I am still having trouble if there is MORE than one concrete instance of the interface.

A little Stack Overflow search seems to indicate that you can either make named instances of the interface and register them both then call them by name.

Or you can register all the instance types and pass an enumeration of the instances to the class you're injecting to.

I guess I just have trouble because I can see a situation now where I want to have 2 different types of Doc Management, but I don't WANT to have 2 different interfaces. I want them both to inherit the same interface as their contract. But with DI I have to register at the interface level and that confusses me!

#194724
Jun 28, 2018 21:28
Vote:
 

As most IOC containers work is that you will get the latest registered instance when querying for a single instance like IServiceLocator.GetInstance<IMyInterface>(), if you call IServiceLocator.GetAllInstances<IMyInterface>() you will get all registered instances. 

There are a bunch of alternatives if you want to control which instance that is returned when querying for a single instance. You can use ModuleDependencyAttribute on your IConfigurableModule instance to set that a specific module should execute after another one. Another alternative is to hook up an event handler for ServiceConfigurationContext.ConfigurationCompleted and in the eventhandler register the instance you want as the default one.

If you instead where to replace one registration you could use Intercept<IMyInterface>()

Yet another alterntive is to use extension method .StructureMap() and register the interfaces as named instances (named instances are supported by StructureMap). Note however that then you need to request the dependency with the registered name/key to get a specific one (I think one registration will be default and returned when asking without name/key, probably the last registered) 

#194731
Edited, Jun 29, 2018 9:13
Vote:
 

and keep in mind that either ServiceLocator or Injected<T> are anti-patterns and should be avoided in favor of constructor injection or any other available DI pattern (except in cases where it's absolutely is not possible).

#194801
Jul 03, 2018 15:42
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.