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

1 Answer 1

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"))));
Sign up to request clarification or add additional context in comments.

2 Comments

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?
@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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.