zoukankan      html  css  js  c++  java
  • Contextual Binding

    Contextual Binding,上下文绑定,即根据不同的环境使用不同接口的实例。

    先说下为什么要使用上下文绑定。

    希望大家能学到更多的东西,多想想为什么,这点会对你产生非常大的影响。

    通常我们会有这么几种需求:

    1 Multiple bindings,多重绑定,用于多重的注入。

    多重绑定,我们的对象其实是一组接口的集合。用代码的方式就是这样,程序员最喜欢的~~~

    class Warrior 
    {
        readonly IEnumerable<IWeapon> _weapons;
        public Warrior( IEnumerable<IWeapon> weapons) {
            _weapons=weapons;
        }
        public void Attack(string victim) {
            foreach(var weapon in _weapons) 
                Console.WriteLine(weapon.Hit(victim));
        }
    }

    2  Simple constrained resolution: Named bindings,简单约束,命名绑定

    命名绑定:最简单也是最常用的方式,通过不同的条件进行绑定。代码就是 :

    Bind<IWeapon>().To<Shuriken>().Named("Strong");
    Bind<IWeapon>().To<Dagger>().Named("Weak");
    实现的时候:
    class WeakAttack {
        readonly IWeapon _weapon;
        public([Named("Weak")] IWeapon weakWeapon)
            _weapon = weakWeapon;
        }
        public void Attack(string victim){
            Console.WriteLine(_weapon.Hit(victim));
        }
    }

    还有一种实现的方式:

    kernel.Get<IWeapon>("Weak");  //服务定位,这是一种反模式
    有兴趣的可以看看这篇文章:

    反模式

    还有几种比较难的,上代码,喜欢研究的可以深入  地址:上下文绑定

    // will work just as well without this line, but it's more correct and important for IntelliSense etc.
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
        AllowMultiple = true, Inherited = true)]
    public class Swimmer : ConstraintAttribute {
        public bool Matches(IBindingMetadata metadata) {
            return metadata.Has("CanSwim") && metadata.Get<bool>("CanSwim");
        }
    }
    class WarriorsModule : Ninject.Modules.NinjectModule {
        public override void Load() {
            Bind<IWarrior>().To<Ninja>();
            Bind<IWarrior>().To<Samurai>().WithMetadata("CanSwim", false);
            Bind<IWarrior>().To<SpecialNinja>().WithMetadata("CanSwim", true);
        }
    }
    class AmphibiousAttack {
        public AmphibiousAttack([Swimmer]IWarrior warrior) {
            Assert.IsType<SpecialNinja>(warrior);
        }
    }
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, 
        AllowMultiple = true, Inherited = true)]
    public class NonSwimmer : ConstraintAttribute {
        public override bool Matches(IBindingMetadata metadata) {
            return metadata.Has("CanSwim") && !metadata.Get<bool>("CanSwim");
        }
    }
    class OnLandAttack {
        public OnLandAttack([NonSwimmer]IWarrior warrior) {
            Assert.IsType<Samurai>(warrior);
        }
    }
    class JustAttack {
        // Note: This will fail because we have three matching bindings.
        public JustAttack(IWarrior warrior) {
        }
    }
    Bind<IWarrior>().To<Samurai>().WhenInjectedInto(typeof(OnLandAttack));
    Bind<IWarrior>().To<SpecialNinja>().WhenInjectedInto(typeof(AmphibiousAttack));
    class SwimmerNeeded : Attribute{}
    class ClimberNeeded : Attribute{}
    class WarriorsModule : Ninject.Modules.NinjectModule {
        public override void Load() {
            Bind<IWarrior>().To<Ninja>();
            Bind<IWarrior>().To<Samurai>().WhenClassHas<ClimberNeeded>();
            Bind<IWarrior>().To<Samurai>().WhenTargetHas<ClimberNeeded>();
            Bind<IWarrior>().To<SpecialNinja>().WhenMemberHas<SwimmerNeeded>();
        }
    }
    class MultiAttack {
        public MultiAttack([ClimberNeeded] IWarrior MountainWarrior) {
        }
        [Inject, SwimmerNeeded]
        IWarrior OffShoreWarrior { get; set; }
        [Inject]
        IWarrior AnyOldWarrior {get;set;}
    }
    
    [ClimberNeeded]
    class MountainousAttack {
        [Inject, SwimmerNeeded]
        IWarrior HighlandLakeSwimmer { get; set; }
        [Inject]
        IWarrior StandardMountainWarrior { get; set; }
    }
    Bind<IWarrior>().To<Samurai>().When(request => request.Target.Member.Name.StartsWith("Climbing"));
    Bind<IWarrior>().To<Samurai>().When(request => request.Target.Type.Namespace.StartsWith("Samurais.Climbing"));
    class ClassThatLogs {
        ILog _log = LogFactory.CreateLog(typeof(ClassThatLogs));
        // Sometimes one sees reflection based approaches too, which have efficiency issues
    }
    Bind<ILog>().ToMethod( context => LogFactory.CreateLog( context.Request.Target.Type ) );
    class ClassThatLogs {
        readonly ILog _log;
        public ClassThatLogs(ILog log){
            _log = log;
        }
    }
  • 相关阅读:
    09-导入/导出
    django 登录
    python 数据结构
    Django 加密解密
    MySQL SQL语句
    libpython3.6m.so.1.0文件缺失
    环境变量配置
    Django 设置session过期时间
    Django 搜索功能
    表单校验
  • 原文地址:https://www.cnblogs.com/fengxing/p/2415122.html
Copyright © 2011-2022 走看看