繁体   English   中英

Ninject WebAPI依赖项与参数

[英]Ninject WebAPI dependency with a parameter

我正在尝试使用这个小库第一次设置Ninject。 我有一个基本控制器,当前看起来像这样:

public class BaseController : ApiController
{

    // Private properties
    private IModelFactory factory;

    // Public properties
    public IServiceInterface Connection { get; private set; }
    public IModelFactory Factory { get { return this.factory ?? (this.factory = new ModelFactory()); } }

    /// <summary>
    /// Default constructor
    /// </summary>
    public BaseController()
    {

        // Get our database settings
        var setting = ConfigurationManager.AppSettings["Server"].ToUpper();
        var type = (setting == "LIVE") ? ServiceInterface.ServerType.Azurerelay_live : ServiceInterface.ServerType.Azurerelay_test;

        try
        {

            // Apply to our public properties
            this.Connection = new ServiceInterface(type);

        } catch
        {

            // Throw a 401 error
            throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
        }
    }
}

我想在此构造函数上使用Ninject,但似乎无法弄清楚如何执行ServiceInterface,因为它需要一个参数。 我试图这样绑定服务:

// List and Describe Necessary HttpModules
// This class is optional if you already Have NinjectMvc
public class NinjectHttpModules
{
    //Return Lists of Modules in the Application
    public static NinjectModule[] Modules
    {
        get
        {
            return new[] { new MainModule() };
        }
    }

    //Main Module For Application
    public class MainModule : NinjectModule
    {
        public override void Load()
        {
            //TODO: Bind to Concrete Types Here
            Kernel.Bind<IServiceInterface>().To<ServiceInterface>();
            Kernel.Bind<IFactory>().To<Factory>();
        }
    }
}

并将我的构造函数更改为此:

public class BaseController : ApiController
{

    // Public properties
    public readonly IServiceInterface Connection;
    public readonly IModelFactory Factory;

    /// <summary>
    /// Default constructor
    /// </summary>
    public BaseController(IServiceInterface connection, IModelFactory factory)
    {

        try
        {

            // Apply to our public properties
            this.Connection = connection;
            this.Factory = factory;

        } catch
        {

            // Throw a 401 error
            throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
        }
    }
}

但这是行不通的,因为ServiceInterface需要一个参数来说明它是否处于活动状态。 有谁知道我如何使此代码起作用?

防止在运行时从AppSettings类的位置读取配置值。 不仅不需要多次阅读它们(性能),而且在整个应用程序中分散使用它们对可维护性和可靠性也有深远的影响。 而是将配置值的检索移到应用程序的启动路径。 这个:

  • 避免重复读取它们,允许应用程序在缺少值时快速失败。
  • 由于类可以放松对配置系统的依赖,因此可以提高可测试性。
  • 将访问这些配置值的位置保持在一个位置,从而使更改应用程序或配置文件的结构变得更加容易。

您的合成根应该看起来像这样:

public override void Load()
{
    var setting = ConfigurationManager.AppSettings["Server"].ToUpper();
    var type = (setting == "LIVE")
        ? ServiceInterface.ServerType.Azurerelay_live
        : ServiceInterface.ServerType.Azurerelay_test;

    Kernel.Bind<IServiceInterface>().ToMethod(c => new ServiceInterface(type));
    Kernel.Bind<IModelFactory>().ToMethod(c => new ModelFactory());
}

另一件事是,您应该赞成继承而不是继承 基类是设计问题的标志。 因此, IModelFactory基类并将IModelFactoryIServiceInterface注入需要使用它们的具体类的构造函数中:

public class HomeController : ApiController
{
    private readonly IModelFactory modelFactory;
    private readonly IServiceInterface serviceInterface;

    public HomeController(IModelFactory modelFactory, IServiceInterface serviceInterface) 
    {
        this.modelFactory = modelFactory;
        this.serviceInterface = serviceInterface;
    }

    // actions here
}

还应避免在构造函数中执行任何操作,除了存储传入的依赖项。 您的注入构造函数应该很简单 这包括抛出异常之类的事情。 防止从构造函数中引发异常,因为这会使解析对象图变得不可靠

避免使用Service Locator反模式 ,确保组件仅具有一个构造函数 ,不要向其注入任何运行时数据,并注意构造函数的过度注入 ,因为这表明违反了“ 单一职责原则”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM