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;
    }
}
posted @ 2012-03-25 23:42  陈卓杰  阅读(514)  评论(0编辑  收藏  举报