Ninject使用指南

1、Ninject依赖链注入:

public  class ShoppingCart
    {
        private IValueCalc calc;
        public ShoppingCart(IValueCalc ivc)
        {
            calc = ivc;
        }
        public decimal Total()
        {
            var prods = new[]
            {
                new Product{Name ="a",Price =15},
                new Product{Name="b",Price =25},
                new Product{Name ="c",Price =35}
            };
            return calc.ValueProducts(prods);
        }
    }

public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }

    public interface IValueCalc
    {
        decimal ValueProducts(params Product[] prods);
    }

    public class LinqValueCalc : IValueCalc
    {
        private IDiscount dis;
        public LinqValueCalc(IDiscount dis)
        {
            this.dis = dis;
        }
        public System.Decimal ValueProducts(params Product[] prods)
        {
            return dis.DiscountTotal(prods.Sum(p => p.Price));
        }
    }

    public interface IDiscount
    {
        decimal DiscountTotal(decimal total);
    }

    public class DiscountHelper:IDiscount
    {

        public decimal DiscountTotal(decimal total)
        {
            return total * 0.9m;
        }
    }

会发现ShoppingCart与LinqValueCalc解耦(借助于IValueCalc),LinqValueCalc与DiscountHelper解耦(借助于IDiscount),这样就形成了依赖链,还可以在DiscountHelper和其他类解耦(也是借助必要的接口),一直这样嵌套下去。

而是用Ninject只需注册bind就可以了 ,如:

static void Main(string[] args)
        {
            IKernel ninjectKernel = new StandardKernel();
            ninjectKernel.Bind<IValueCalc>().To<LinqValueCalc>();
            ninjectKernel.Bind<IDiscount>().To<DiscountHelper>();//将内嵌接口绑定到实现
            IValueCalc cal = ninjectKernel.Get<IValueCalc>();//ninject在获取IValueCalc实现时,会自动发现内嵌的接口,并自动注入依赖,实现依赖链的注入
            Console.WriteLine("Total:{0:C}", new ShoppingCart(cal).Total());
            Console.ReadKey();
        }

2、在依赖注入时,通过属性或构造函数的参数,动态传递值

在上面的例子中,折扣是9折:return total*0.9,如果想要动态(比如说不同商品的折扣从数据库中取)传递折扣值,那么可以这样改造DiscountHelper类:

public class DiscountHelper:IDiscount
    {
        public decimal disAmount { get; set; }
        public decimal DiscountTotal(decimal total)
        {
            return total * (1-disAmount);
        }
    }

相应的ninject绑定代码就变成了:ninjectKernel.Bind<IDiscount>().To<DiscountHelper>().WithPropertyValue("disAmount",0.5m);//注意最后的方法调用

同样也可以使用构造函数:

public class DiscountHelper:IDiscount
    {
        public decimal disAmount { get; set; }

        private decimal disParam;
        public DiscountHelper(decimal disParam)
        {
            this.disParam = disParam;
        }
        public decimal DiscountTotal(decimal total)
        {
            return total * (1-disParam);
        }
    }

绑定语句:ninjectKernel.Bind<IDiscount>().To<DiscountHelper>().WithConstructorArgument("disParam", 0.4m);

3、自我绑定,由第一个特性可知,如果我们使用依赖的最外层类,那么会依次实现内层的自动依赖注入,那么ninject支持自我绑定,

可以将如下代码:

IValueCalc cal = ninjectKernel.Get<IValueCalc>();

ShoppingCart sc=new ShoppingCart(cal);

替换成更简洁的方式:ShoppingCart sc=ninjectKernel.Get<ShoppingCart>();

4、上述我们依赖注入是通过接口,也可以使用抽象类实现同样的功能,具体写法:ninject.Bind<抽象类>.To<实现类>();

5、条件依赖注入,即如果一个接口或抽象类有不同的实现,那么可以在解耦时,绑定不同的实现,具体语法:

ninject.Bind<接口或抽象类>.To<特定的实现类(多个中的一个)>.WhenInjectInto<依赖类(多个依赖类中的一个)>;

原文地址:https://www.cnblogs.com/xiamou/p/3463402.html