【问题标题】:Asp.Net MVC and Strategy patternAsp.Net MVC 和策略模式
【发布时间】:2015-05-27 20:10:14
【问题描述】:

我有一个使用实体框架的 MVC 应用程序。我正在使用存储库、工作单元和统一作为依赖注入。

我的问题是我有不同的身份验证类型,每种类型我想要一个不同的类,所以我决定使用策略模式

    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();
        }
    }

我的问题是我将IAuthStrategy 注入控制器,它给了我一个错误,因为我没有实现IAuthStrategy,而是将它传递给AuthStrategy 构造函数,正如您在我的代码中看到的那样.

我该如何解决这个错误?

这是我的控制器

 public class EmployeeController : ApiController
        {

            private IAuthStrategy _auth;

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

            }}
    }

这是我注册类型的统一配置

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);

    }
}

【问题讨论】:

  • 好的 - 你需要为你的问题提供一些额外的上下文。您能否向我们展示您如何通过 Unity 注册您的课程,向您的控制器展示您将 IAuthStrategy 传递到其中,以及您收到的确切错误消息。
  • 报错怎么办?只是说您遇到了错误,而没有详细说明实际错误是什么,这很难提供帮助。
  • 这里出现错误:错误 1 ​​类型“HRBL.AuthStrategy”不能用作泛型类型或方法“Microsoft.Practices.Unity.UnityContainerExtensions.RegisterType(Microsoft.Practices.Unity.IUnityContainer,参数 Microsoft.Practices.Unity.InjectionMember[])'。没有从“HRBL.AuthStrategy”到“HRBL.IAuthStrategy”的隐式引用转换。 C:\Farhan\Angular\SogetiEmployees\SogetiEmployees\App_Start\UnityConfig.cs 49 13 SogetiEmployees
  • 那是因为你要求unity注册AuthStrategyIAuthStrategy,而它没有实现接口。如果您想使用传递给控制器​​的AuthStrategy 实例,然后要求它在运行时使用IAuthStrategy,您将需要另一个接口并注册它。
  • 我知道,你能告诉我解决办法吗?

标签: asp.net-mvc entity-framework-6 repository-pattern strategy-pattern


【解决方案1】:

你的单元注册和课程看起来有点不对劲。

据我所知,这是你真正想做的。

设置一个工厂,它将在运行时确定应该使用哪个 IAuthStrategy

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;
    }
}

这是你现有的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();
    }
}

统一注册工厂:

container.RegisterType<IAuthStrategyFactory, AuthStrategyFactory>();

在您的控制器中:

public class EmployeeController : ApiController
{
    private IAuthStrategy _auth;

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

【讨论】:

  • 公共类 EmployeeController : ApiController { private IAuthStrategy _auth; public EmployeeController(IEmployeeBL employeeBL, IAuthStrategyFactory auth) { this._auth = auth.GetAuthStrategy(); }} container.RegisterType();
  • 感谢 Brendan 的帮助,我解决了这个问题,但我面临另一个问题,现在我添加了更多正在实施 IAuthStrategy 的 cals,现在问题是统一正在解决这个问题,但总是执行我刚刚执行的新类已实现,如果您还可以,我也可以分享该代码以加深理解。
【解决方案2】:

实际上我错过了在 AuthStrategyFactory 上实现的 IAuthStrategyFactory,一旦我在统一容器中实现并注册就可以了。

谢谢

【讨论】:

    猜你喜欢
    • 2010-11-04
    • 2013-04-13
    • 1970-01-01
    • 2019-03-03
    • 2011-04-09
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多