Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have an MVC application that uses Entity Framework. I am using a repository, unit of work and unity as dependency injection.

The problem I have is that I have different authentication types, and each type I want a different class, so I decided to use the Strategy pattern

    public interface IAuthStrategy
    {
        OperationResponse<AuthenticationMechanismDTO> GetAuthenticationMechanism(string userName);
    }

    public class AuthStrategy 
    {
        readonly IAuthStrategy _authStrategy;

        public AuthStrategy(IAuthStrategy authStrategy)
        {
            this._authStrategy = authStrategy;
        }

        public OperationResponse<AuthenticationMechanismDTO> GetAuthenticationMechanism(string userName)
        {
            return _authStrategy.GetAuthenticationMechanism(userName);

        }

    }



    public class UserNamePasswordMechanism : IAuthStrategy
    {

        private IInstitutionRepository _institutionRepository;

        public UserNamePasswordMechanism(IInstitutionRepository institutionRepository)
        {
            this._institutionRepository = institutionRepository;
        }

        public OperationResponse<AuthenticationMechanismDTO> GetAuthenticationMechanism(string userName)
        {

            throw new NotImplementedException();
        }
    }

My problem is that I am injecting IAuthStrategy into the controller, and it gives me an error, because instead of implementing IAuthStrategy, I am passing that to AuthStrategy constructor, as you can see that in my code.

How can I fix this error?

Here is my controller

 public class EmployeeController : ApiController
        {

            private IAuthStrategy _auth;

            public EmployeeController(IAuthStrategy auth)
            {
                this._employeeBL = employeeBL;
                this._auth = auth;

            }}
    }

Here is unity config where i am registering my types

public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>


   public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your types here

        container.RegisterType<IInstitutionRepository, InstitutionRepository>();

        container.RegisterType<IAuthStrategy, AuthStrategy>();

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);

    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
135 views
Welcome To Ask or Share your Answers For Others

1 Answer

Your unit registrations and classes look a little off.

From what I can gather, this is what you really want to do.

Setup a factory that will determine at runtime which IAuthStrategy should be used:

public interface IAuthStrategyFactory
{
    IAuthStrategy GetAuthStrategy();
}

public class AuthStrategyFactory : IAuthStrategyFactory
{
    readonly IAuthStrategy _authStrategy;

    public AuthStrategy(...)
    {
        //determine the concrete implementation of IAuthStrategy that you need
        //This might be injected as well by passing 
        //in an IAuthStrategy and registering the correct one via unity  at startup.
        _authStrategy = SomeCallToDetermineWhichOne(); 
    }

    public IAuthStrategy GetAuthStrategy() 
    {
        return _authStrategy;
    }
}

This is your existing AuthStrategy:

public interface IAuthStrategy
{
    OperationResponse<AuthenticationMechanismDTO> GetAuthenticationMechanism(string userName);
}

public class UserNamePasswordMechanism : IAuthStrategy
{

    private IInstitutionRepository _institutionRepository;

    public UserNamePasswordMechanism(IInstitutionRepository institutionRepository)
    {
        this._institutionRepository = institutionRepository;
    }

    public OperationResponse<AuthenticationMechanismDTO> GetAuthenticationMechanism(string userName)
    {

        throw new NotImplementedException();
    }
}

Register the factory with unity:

container.RegisterType<IAuthStrategyFactory, AuthStrategyFactory>();

In your controller:

public class EmployeeController : ApiController
{
    private IAuthStrategy _auth;

    public EmployeeController(IAuthStrategyFactory authFactory)
    {
        this._employeeBL = employeeBL;
        this._auth = authFactory.GetAuthStrategy();
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...