1

I wanna resolve different instances with the same interface. I read something about named registrations which should probably push me in the right direction except I can't seem to fit them in a hierarchy structure.

public interface IServiceType
{

}

public interface IServiceDependancy
{

}

public class main
{
  var container = new UnityContainer();
  container.RegisterType(typeof(IServiceType), typeof(ServiceType));
  container.RegisterType(typeof(IServiceDependancy), typeof(ProductionServiceDependancy), "Production");
  container.RegisterType(typeof(IServiceDependancy), typeof(TestServiceDependancy), "Test");
}

How can I resolve the IServiceType twice (or more)?

  • First time with my TestServiceDependancy.
  • Second time with my ProductionServiceDependancy

Kind regards

Luuk Krijnen
  • 1,180
  • 3
  • 14
  • 37

1 Answers1

2

It seems to me that you don't need named registrations. Since you are talking about a ProductionServiceDependency and TestServiceDependency you would typically just want to register either one of them, and only use a different one when the application is restarted (because of a different configuration setting). In other words, you can simply do this:

if (ConfigurationManager.AppSettings["IsTest"] != string.Empty) {
   container.RegisterType(typeof(IServiceDependency), typeof(TestServiceDependancy));
else
   container.RegisterType(typeof(IServiceDependency), typeof(ProductionServiceDependency));

Or perhaps simply:

container.RegisterType(typeof(IServiceDependency),
    ConfigurationManager.AppSettings["IsTest"] != string.Empty
        ? typeof(TestServiceDependency)
        : typeof(ProductionServiceDependency));

In case you need to be able to swap the implementation based on some runtime condition (perhaps because you need to be able two change the configuration at runtime), you should hide the two implementations behind a proxy:

 public sealed class ServiceDependencySelectionProxy : IServiceDependency {
      private Func<bool> selectionPredicate;
      private IServiceDependency trueService;
      private IServiceDependency falseService;

      public ServiceDependencySelectionProxy(Func<bool> selectionPredicate,
          IServiceDependency trueService, IServiceDependency falseService) {
          this.selectionPredicate = selectionPredicate;
          this.trueService = trueService;
          this.falseService = falseService;
      }

      object IServiceDependency.ItsMethod(object param) {
          return this.selectionPredicate()
              ? this.trueService.ItsMethod(param)
              : this.falseService.ItsMethod(param);
      }
 }

Now you can register the ServiceDependencySelectionProxy as IServiceDependency and this will hide the fact that there is a some runtime selection going on, while keeping your object graph itself completely static (as in: its structure wont change at runtime) and this keeps your object graph verifiable.

Here's an example of how to register this ServiceDependencySelectionProxy:

container.RegisterType<IServiceDependancy, ProductionServiceDependancy>("Production");
container.RegisterType<IServiceDependancy, TestServiceDependancy>("Test");
container.Register<IServiceDependency>(new InjectionFactory(c =>
    new ServiceDependencySelectionProxy(
        () => IsApplicationTestSwitchEnabled(),
        container.Resolve<IServiceDependency>("Test"),
        container.Resolve<IServiceDependency>("Production"))));
Steven
  • 166,672
  • 24
  • 332
  • 435
  • There is no selection. It's a project for synchronizing users between different environments. So first production in synchronized en then the same service code should be used with different database dependencies. Is the proxy still valid in this case or are other solutions preferred? – Luuk Krijnen Sep 14 '15 at 11:47
  • @LuukKrijnen: That seems like a runtime decision, and in that case a proxy is probably the best approach. Just remember one thing: don't make runtime decisions while resolving the object graph. – Steven Sep 14 '15 at 12:23