0

I seem to be stumped on how to implemented the strategy pattern with a DI container.

I have a strategy interface:

public interface IUserCompaniesInviteStrategy
    {
        bool InviteUserToCompany(UserCompaniesInviteRequest userCompaniesInviteRequest);
    }

and a couple of concrete classes:

public class ConcreteExistingUserInviteStrategy : IUserCompaniesInviteStrategy

public class ConcreteNewUserInviteStrategy : IUserCompaniesInviteStrategy

How do I wire up Unity with this?

    container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>();
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>();

obviously doesn't work...

I tried:

container.RegisterType<IUserCompaniesInviteStrategy<ConcreteExistingUserInviteStrategy>, ConcreteExistingUserInviteStrategy>();
        container.RegisterType<IUserCompaniesInviteStrategy<ConcreteNewUserInviteStrategy>, ConcreteNewUserInviteStrategy>();

with

public interface IUserCompaniesInviteStrategy<T>

That doesn't seem to work.

I think what I'd like to do here is use named types, so like:

container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>("1");
            container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>("2");

However, I have constructor injection setup and using container.resolve isn't a good option for me because of n-tier architecture and chaining dependencies I'd have to resolve.

How can I inject a named type into a constructor? Is there a better way to do what I'm trying to do? (Create an interface that resolves to two concrete strategies)

Update:

I took a look at With Unity how do I inject a named dependency into a constructor? . The accepted answer won't work because I don't have a dependency on Unity in my domain, nor do I want it. I tried the StrategyResolver, but I'm getting:

  An error occurred when trying to create a controller of type 'UserController'. Make sure that the controller has a parameterless public constructor.

That is indicative of a DI problem.

The StrategyResolver and IStrategyResolver are the same as in the example:

public class StrategyResolver : IStrategyResolver
    {
        private IUnityContainer container;

        public StrategyResolver(IUnityContainer unityContainer)
        {
            this.container = unityContainer;
        }

        public T Resolve<T>(string namedStrategy)
        {
            return this.container.Resolve<T>(namedStrategy);
        }
    }

public interface IStrategyResolver
    {
        T Resolve<T>(string namedStrategy);
    }

My config:

container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>("ExistingUser");
            container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>("NewUser");
            container.RegisterType<IStrategyResolver, StrategyResolver>();
            container.RegisterType<IUserFactory, UserFactory>();

Concretes:

public class ConcreteExistingUserInviteStrategy : IUserCompaniesInviteStrategy
public class ConcreteNewUserInviteStrategy : IUserCompaniesInviteStrategy

And then I call it like:

_strategyResolver.Resolve<IUserCompaniesInviteStrategy>("ExistingUser");

Not sure what's wrong with it.

RandomUs1r
  • 4,010
  • 1
  • 24
  • 44
  • Possible duplicate of [With Unity how do I inject a named dependency into a constructor?](https://stackoverflow.com/questions/7046779/with-unity-how-do-i-inject-a-named-dependency-into-a-constructor) – Kenneth K. Jun 29 '17 at 19:06
  • See [Dependency Injection Unity - Conditional resolving](https://stackoverflow.com/a/32415954/181087) – NightOwl888 Jun 29 '17 at 23:41
  • When you start having multiple implementations for the same interface, DI containers become in the way. I advice you to stop using a container and use [Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di/) instead. See this article for more details: http://criticalsoftwareblog.com/index.php/2015/08/23/why-di-containers-fail-with-complex-object-graphs/ – Yacoub Massad Jun 30 '17 at 10:07
  • Pure DI doesn't mean "Don't use a container". It means "Think about it in an absolute manner, not constrained by a container, and you might use one if there are benefits of doing so". – Tipx Jul 06 '17 at 16:33

0 Answers0