[英]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
基类并将IModelFactory
和IServiceInterface
注入需要使用它们的具体类的构造函数中:
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.