C# 其他层中的依赖项发现';使用Ninject.MVC3的s模块
主要问题:如何发现在其他层中配置了Ninject.MVC3的依赖关系 背景: 我正在我的一个ASP.NET MVC4项目中使用Ninject.MVC3 我以前使用过ServiceLocator,但对Ninject来说是新的。通过新的增强功能,Ninject的设置和配置非常简单 在新的Ninject.MVC3 Nuget包中,将一个“C# 其他层中的依赖项发现';使用Ninject.MVC3的s模块,c#,asp.net-mvc-4,ninject,C#,Asp.net Mvc 4,Ninject,主要问题:如何发现在其他层中配置了Ninject.MVC3的依赖关系 背景: 我正在我的一个ASP.NET MVC4项目中使用Ninject.MVC3 我以前使用过ServiceLocator,但对Ninject来说是新的。通过新的增强功能,Ninject的设置和配置非常简单 在新的Ninject.MVC3 Nuget包中,将一个“NinjectWebCommon”类添加到web项目的App_Start文件夹中,我们在其中配置所有依赖项。这个类是静态的,除了返回void的Start和Stop静态
NinjectWebCommon
”类添加到web项目的App_Start文件夹中,我们在其中配置所有依赖项。这个类是静态的,除了返回void的Start和Stop静态方法外,不公开任何外部内容
为了使用它,您可以在其“RegisterServices
”方法中配置依赖项,例如
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDataContext>().To<MyDataContext>().WithConstructorArgument("connectionString", "name=MyDataContext");
kernel.Bind<IRoleService>()
.To<RoleService>()
.WithConstructorArgument("dbContext", context => context.Kernel.Get<IDataContext>());
}
现在假设我们想向这个类添加一个新的依赖项,比如ILoggerRoleService
。目前我必须这样做:
public class RoleService : IRoleService
{
private readonly IDataContext _dbContext;
private ILogger _logger;
public RoleService(IDataContext dbContext, ILogger logger)
{
_dbContext = dbContext;
_logger = logger;
}
}
我想知道这是允许模块发现依赖关系的唯一(或理想或标准)方法吗
使用ServiceLocator
我会这样做:
public class RoleService : IRoleService
{
private readonly IDataContext _dbContext;
private readonly Lazy<ILogger> _logger;
public RoleService(IDataContext dbContext)
{
_dbContext = dbContext;
_logger = Locator.Current.GetInstanceLazy<ILogger>();
}
}
在存在于业务层中的RoleService类中。该属性未初始化并设置为null。我应该如何使Ninject初始化它,请注意Ninject初始化是在MVCWeb项目中完成的
总结我的问题如下:
2) 您应该在层的底部创建StandardKernel对象集,包括UI项目在内的每个组件都应该使用该对象
3) 您必须通过ninject进行实例化。Ninject将填充构造函数参数,并搜索属性注入的类型。
例如:
public interface IBusinessClass {
int DoWork();
}
public class BusinessClass : IBusinessClass
{
public int DoWork()
{
return 10;
}
}
public interface IBusinessClass2
{
int DoWork2();
}
public class BusinessClass2 : IBusinessClass2
{
public int DoWork2()
{
return 20;
}
}
public class Consumer
{
public IBusinessClass2 BusinessClass2 { get; set; }
[Inject]
public IBusinessClass BusinessClass { get; set; }
public Consumer(IBusinessClass2 businessClass2)
{
BusinessClass2 = businessClass2;
}
}
class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Bind<IBusinessClass>()
.To<BusinessClass>();
kernel.Bind<IBusinessClass2>()
.To<BusinessClass2>();
Consumer c = kernel.Get<Consumer>();
Console.WriteLine(c.BusinessClass.DoWork());
Console.WriteLine(c.BusinessClass2.DoWork2());
Console.ReadKey();
}
}
修改此方法n以使用新内核,但不使用基本库中的内核:
private static IKernel CreateKernel()
{
var kernel = // kernel from base library
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
private静态IKernel CreateKernel()
{
var kernel=//来自基本库的内核
kernel.Bind().ToMethod(ctx=>()=>newbootstrapper().kernel);
kernel.Bind().To();
注册服务(内核);
返回内核;
}
谢谢你,彼得。考虑到我们有多层arch,我们应该创建一个单独的库项目,在其中添加Ninject并使用依赖项配置它。在预启动或启动期间的web项目中,我们将初始化这个新库。我做对了吗?现在要尝试一下……您可以在其他库中使用webactivator:[assembly:WebActivatorEx.PreApplicationStartMethod(typeof(className),“parameterlessStaticMethodOfThatClass”)]创建了一个单独的库项目,并在其中安装了Ninject。配置了一个依赖项。Web项目具有对此程序集的引用,正在调用调试启动方法。但是,现在没有调用具有参数的控制器ctor。“没有为此对象定义无参数构造函数。”我将[Inject]放在控制器ctor中,但存在相同的问题。我想我必须做些额外的事情,让Ninject在项目之间共享,并进行探索。有什么建议吗?再次感谢@Péter。这听起来是一个很有吸引力的解决方案。我将在今天实施并接受您的回答。谢谢
public interface IBusinessClass {
int DoWork();
}
public class BusinessClass : IBusinessClass
{
public int DoWork()
{
return 10;
}
}
public interface IBusinessClass2
{
int DoWork2();
}
public class BusinessClass2 : IBusinessClass2
{
public int DoWork2()
{
return 20;
}
}
public class Consumer
{
public IBusinessClass2 BusinessClass2 { get; set; }
[Inject]
public IBusinessClass BusinessClass { get; set; }
public Consumer(IBusinessClass2 businessClass2)
{
BusinessClass2 = businessClass2;
}
}
class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Bind<IBusinessClass>()
.To<BusinessClass>();
kernel.Bind<IBusinessClass2>()
.To<BusinessClass2>();
Consumer c = kernel.Get<Consumer>();
Console.WriteLine(c.BusinessClass.DoWork());
Console.WriteLine(c.BusinessClass2.DoWork2());
Console.ReadKey();
}
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
private static IKernel CreateKernel()
{
var kernel = // kernel from base library
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}