0
votes

I am trying to inject two classes into my constructor, the problem they are both of the same interface. My registering is:

container.RegisterType<ITrackerSection, ScopeSection>();
container.RegisterType<ITrackerSection, SampleSection>();

As you can see they are both of type ITrackerSection but have different implementations. My constructor looks as follows:

public TrackerEngine(ITrackerSection scopeSection, ITrackerSection sampleSection)

Both these parameters are injected as a sampleSection as it was last to be registered for the interface type. I have no problem with naming the registered types for example

container.RegisterType<ITrackerSection, ScopeSection>("scopeSection");
container.RegisterType<ITrackerSection, SampleSection>("sampleSection");

But this now means I have to specify the classes parameters and that seems messy and adding dependency when unity is more than capable of resolving them. Furthermore the registering of the TrackerEngine would also need to specify the parameters. I know I could use an in line attribute in the constructor of TrackerEngine but I would prefer Unity to infer the objects by the names.

Can Unity (I can not seem to get this working) correctly inject the correct implementation of the interface purely from the name given to the parameter in the constructor? So ITrackerSection scopeSection is the same name given in the registering of ScopeSection so use that type.

1
Why are those two classes implement the same interface? Your design seems ambiguous. If you give them each their own interface all your problems are gone. - Steven
Creating interfaces specific to each type seems an anti pattern. The interface defines a structure all of these sections need to have. IScopeSection : ITrackerSection seems to be extra code to solve a problem that shouldn't exist - Edward Wilson
ambiguity is an anti-pattern as well. - Steven

1 Answers

0
votes

I agree with the comments regarding sharing the interface. The whole point of IOC is that your engine should not need to know which implementation to use. It should only be given the interface.

A way to solve this is to allow Unity to inject an array of interfaces:

public TrackerEngine(ITrackerSection[] trackerSections) { }

This way you can inject both. But then, if you really need to know which interface is which, you could implement a enum or something in your interface. Something like this:

public interface ITrackerSection {
   SectionType Section { get; }
}

public enum SectionType{
   0 = Scope,
   1 = Sample
}

And in your implementation:

public class ScopeTrackerSection : ITrackerSection {
   // Do your stuff...

   public SectionType Section {
      get { return SectionType.Scope; }
   }
}

public class SampleTrackerSection : ITrackerSection {
   // Do your stuff...

   public SectionType Section {
      get { return SectionType.Sample; }
   }
}

And in your Engine, you can fetch the interface needed to the desired action.

public TrackerEngine(ITrackerSection[] trackerSections) {
  var scopeTrackerSection = trackerSections.FirstOfDefault(x => x.Section == SectionType.Sample);

// Do something with scopeTrackerSection

}