Dependency injection Ninject-如何以及何时注射

Dependency injection Ninject-如何以及何时注射,dependency-injection,ninject,Dependency Injection,Ninject,说到DI和ninject,我是个新手,我有点挣扎 关于实际注射应在何时进行以及如何开始注射 绑定 我已经在我的web应用程序中使用了它,而且它在那里工作得很好, 但是现在我想在类库中使用注入 假设我有一门课是这样的: 公共类TestClass { [注入] 公共IRoleRepository角色还原{get;set;} [注入] 公共ISiteRepository站点存储库{get;set;} [注入] 公共IUserRepository UserRepository{get;set;} 私有只

说到DI和ninject,我是个新手,我有点挣扎 关于实际注射应在何时进行以及如何开始注射 绑定

我已经在我的web应用程序中使用了它,而且它在那里工作得很好, 但是现在我想在类库中使用注入

假设我有一门课是这样的:

公共类TestClass
{
[注入]
公共IRoleRepository角色还原{get;set;}
[注入]
公共ISiteRepository站点存储库{get;set;}
[注入]
公共IUserRepository UserRepository{get;set;}
私有只读字符串\u文件名;
公共测试类(字符串文件名)
{
_fileName=文件名;
}
公共无效导入数据()
{
var user=UserRepository.GetByUserName(“myname”);
var role=RoleRepository.GetByRoleName(“myname”);
var site=SiteRepository.GetByID(15);
//使用文件等
}
}
我想在这里使用属性注入,因为我需要传入 我的构造函数中的文件名。如果我需要的话,我说的对吗 传入构造函数参数,我不能使用构造函数注入? 如果我可以将构造函数注入与其他参数一起使用,如何 我把那些参数传进来

我有一个控制台应用程序,它由测试类使用,看起来像 如下:

类程序
{
静态void Main(字符串[]参数)
{
//NinjectRepositoryModule将我的IRoleRepository等绑定到混凝土
//类型和工作良好,因为我在我的web应用程序中使用它,没有任何
//问题
IKernel kernel=新的标准内核(新的NinjectRepositoryModule());
var test=新的TestClass(“文件名”);
test.ImportData();
}
}
我的问题是,当我调用
test.ImportData()
时,我的存储库是空的-没有任何东西被注入到它们中。我尝试创建另一个模块并调用

Bind().ToSelf();
正如我所想,这可能会解决
TestClass
中的所有注入属性,但我一事无成

我肯定这是个小问题,但我就是不知道
如何进行此操作。

您正在直接新建
TestClass
,Ninject无法拦截此操作-请记住,没有像代码转换这样的魔法可以拦截您的
新的

你应该做
kernel.Get

否则,您可以在
new
之后使用
内核注入它

我认为wiki上有一篇文章讨论了
Inject
vs
Get
等等

请注意,一般情况下,直接
Get
Inject
调用是服务位置的一种出错气味,这是一种反模式。在您的web应用程序中,
NinjectHttpModule
PageBase
是拦截对象创建的钩子-在其他样式的应用程序中也有类似的拦截器/逻辑位置可以拦截

对于
Bind().ToSelf()
,通常
StandardKernel
具有
ImplicitSelfBinding=true
,这将使其变得不必要(除非您希望影响其范围而不是
.InTransientScope()

最后一个样式点:-您正在使用属性注入。很少有好的理由这样做,所以您应该改用构造函数注入

还有do go buy,他在这里有一大堆优秀的帖子,涵盖了依赖注入领域的许多重要但微妙的考虑因素。

好的

我已经找到了如何做我需要的,部分感谢你的评论鲁本。我创建了一个新模块,它基本上保存了我在类库中使用的配置。在这个模块中,我可以使用占位符接口绑定,也可以向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; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用Ninject.Core;
使用Ninject.Core.Behavior;
命名空间测试
{
公共课程
{
公共静态void Main(字符串[]args)
{
var kernel=新的标准内核(new RepositoryModule(),new ProgramModule());
var loader=kernel.Get();
loader.LoadCustomer();
Console.ReadKey();
}
}
公共类程序模块:标准模块
{
公共覆盖无效负载()
{
//要让ninject添加构造函数参数,请取消注释下面的行
//Bind().ToSelf().WithArgument(“文件名”,“字符串参数文件名”);
绑定()到();
}
}
公共类RepositoryModule:StandardModule
{
公共覆盖无效负载()
{
使用()将()绑定到();
}
}
公共接口IFileNameContainer
{
字符串文件名{get;}
}
公共类LiveFileName:IFileNameContainer
{
公共字符串文件名
{
获取{返回“实时文件名”;}
}
}
公共类CustomerLoader
{
[注入]
公共ICCustomerRepository CustomerRepository{get;set;}
私有字符串\u文件名;
//要让ninject添加构造函数参数,请取消注释下面的行
//公共CustomerLoader(字符串文件名)
//{
//_fileName=文件名;
//}
公共CustomerLoader(IFileNameContainer fileNameContainer)
{
_fileName=fileNameContainer.fileName;
}
公共客户()
{
Customer c=CustomerRepository.GetCustomer();
Console.WriteLine(string.Format(“Name:{0}\nAge:{1}\n文件名是:{2}”,c.Name,c.Age,_fileName));
}
}
公共接口ICustomerRe