Cia*_*ill 18 dependency-injection ninject
对于DI和ninject来说,我是一个新手,我正在努力解决实际注入何时发生以及如何开始绑定的问题.
我已经在我的Web应用程序中使用它并且它在那里工作正常,但现在我想在类库中使用注入.
说我有这样一个类:
public class TestClass
{
[Inject]
public IRoleRepository RoleRepository { get; set; }
[Inject]
public ISiteRepository SiteRepository { get; set; }
[Inject]
public IUserRepository UserRepository { get; set; }
private readonly string _fileName;
public TestClass(string fileName)
{
_fileName = fileName;
}
public void ImportData()
{
var user = UserRepository.GetByUserName("myname");
var role = RoleRepository.GetByRoleName("myname");
var site = SiteRepository.GetByID(15);
// Use file etc
}
}
Run Code Online (Sandbox Code Playgroud)
我想在这里使用属性注入,因为我需要在构造函数中传入一个文件名.我是否正确说,如果我需要传入一个构造函数参数,我不能使用构造函数注入?如果我可以使用带有附加参数的构造函数注入,我该如何传递这些参数?
我有一个由Test类使用的控制台应用程序,如下所示:
class Program
{
static void Main(string[] args)
{
// NinjectRepositoryModule Binds my IRoleRepository etc to concrete
// types and works fine as I'm using it in my web app without any
// problems
IKernel kernel = new StandardKernel(new NinjectRepositoryModule());
var test = new TestClass("filename");
test.ImportData();
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我调用test.ImportData()我的存储库时为null - 没有注入任何内容.我试过创建另一个模块并调用
Bind<TestClass>().ToSelf();
Run Code Online (Sandbox Code Playgroud)
因为我认为这可能会解决所有的注射性能,TestClass但我无处可去.
我确定这是一个微不足道的问题,但我似乎无法找到如何解决这个问题.
Rub*_*ink 18
你是直接新手TestClass,Ninject无法拦截 - 记住没有像代码转换那样神奇的拦截你new的等等.
你应该这样做kernel.Get<TestClass>.
如果做不到这一点,你可以注入后它,你 new用它kernel.Inject( test);
我认为维基中有一篇关于Injectvs Get等的文章.
请注意,一般情况下,直接Get或Inject电话是服务错误的服务位置气味,这是一个反模式.对于您的Web应用程序,NinjectHttpModule并且PageBase是拦截对象创建的钩子 - 在其他样式的应用程序中有类似的拦截器/逻辑位置来拦截.
重新您Bind<TestClass>().ToSelf(),一般StandardKernel有ImplicitSelfBinding = true这将使不必要的(除非你想影响其范围比其他东西.InTransientScope()).
最后一个风格点: - 你正在使用属性注入.这很少有很好的理由,所以你应该使用构造函数注入.
并且去购买@Mark Seemann的.NET中的Dependency Injection,他在这里有很多优秀的帖子,涵盖了依赖注入区域内和周围的许多重要但微妙的考虑因素.
好,
我已经找到了如何做我需要的东西,部分归功于你的意见Ruben.我创建了一个新模块,它基本上保存了我在类库中使用的配置.在这个模块中,我可以使用占位符接口绑定,也可以将构造函数参数添加到CustomerLoader.下面是虚拟控制台应用程序的代码,用于演示两种方式.
这可能有助于其他人开始使用Ninject!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject.Core;
using Ninject.Core.Behavior;
namespace NinjectTest
{
public class Program
{
public static void Main(string[] args)
{
var kernel = new StandardKernel(new RepositoryModule(), new ProgramModule());
var loader = kernel.Get<CustomerLoader>();
loader.LoadCustomer();
Console.ReadKey();
}
}
public class ProgramModule : StandardModule
{
public override void Load()
{
// To get ninject to add the constructor parameter uncomment the line below
//Bind<CustomerLoader>().ToSelf().WithArgument("fileName", "string argument file name");
Bind<LiveFileName>().To<LiveFileName>();
}
}
public class RepositoryModule : StandardModule
{
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>().Using<SingletonBehavior>();
}
}
public interface IFileNameContainer
{
string FileName { get; }
}
public class LiveFileName : IFileNameContainer
{
public string FileName
{
get { return "live file name"; }
}
}
public class CustomerLoader
{
[Inject]
public ICustomerRepository CustomerRepository { get; set; }
private string _fileName;
// To get ninject to add the constructor parameter uncomment the line below
//public CustomerLoader(string fileName)
//{
// _fileName = fileName;
//}
public CustomerLoader(IFileNameContainer fileNameContainer)
{
_fileName = fileNameContainer.FileName;
}
public void LoadCustomer()
{
Customer c = CustomerRepository.GetCustomer();
Console.WriteLine(string.Format("Name:{0}\nAge:{1}\nFile name is:{2}", c.Name, c.Age, _fileName));
}
}
public interface ICustomerRepository
{
Customer GetCustomer();
}
public class CustomerRepository : ICustomerRepository
{
public Customer GetCustomer()
{
return new Customer() { Name = "Ciaran", Age = 29 };
}
}
public class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16036 次 |
| 最近记录: |