【问题标题】:Ninject conditional binding based on property valueNinject 基于属性值的条件绑定
【发布时间】:2011-03-28 13:44:53
【问题描述】:

我在使用 ninject 定义绑定时遇到问题。

我在一个标准的 ASP.NET WebForms 应用程序中。我已经定义了一个 http 处理程序来在页面和控件中注入依赖项(属性注入)。

这是我想要做的:

我正在创建一个自定义组合框用户控件。基于该组合框上的枚举值,我希望能够在属性中注入不同的对象(我想做的比这更复杂,但对此的回答应该足以让我继续)。

【问题讨论】:

    标签: .net asp.net ninject-2


    【解决方案1】:

    基于属性值的条件绑定不是一个好的设计,甚至是不可能的(至少对于构造函数注入而言),因为依赖项通常是在对象接收它们之前创建的。以后物业改了怎么办?更可取的方法是注入工厂或工厂方法,向 Ninject 请求实例,并在内部交换初始化和属性值更改的策略。

    public enum EntityType { A,B } 
    public class MyControl : UserControl
    {
        [Inject]
        public Func<EntityType, IMyEntityDisplayStrategy> DisplayStrategyFactory 
        { 
            get { return this.factory; }
            set { this.factory = value; this.UpdateEntityDisplayStrategy(); }
        }
    
        public EntityType Type 
        { 
            get { return this.type; } 
            set { this.type = value; this.UpdateEntityDisplayStrategy(); };
        }
    
        private UpdateEntityDisplayStrategy()
        {
            if (this.DisplayStrategyFactory != null)
                this.entityDisplayStrategy = this.DisplayStrategyFactory(this.type);
        }
    }
    
    Bind<Func<EntityType, IMyEntityDisplayStrategy>>
        .ToMethod(ctx => type => 
             type == ctx.kernel.Get<IMyEntityDisplayStrategy>( m => 
                 m.Get("EntityType", EntityType.A));
    Bind<IMyEntityDisplayStrategy>.To<AEntityDisplayStrategy>()
        .WithMetadata("EntityType", EntityType.A)
    Bind<IMyEntityDisplayStrategy>.To<BEntityDisplayStrategy>()
        .WithMetadata("EntityType", EntityType.B)
    

    或者添加一个激活操作并手动注入依赖项。但请注意,更改约束属性会导致状态不一致。

    OnActivation((ctx, instance) => 
        instance.MyStrategy = ctx.Kernel.Get<MyDependency>(m => 
            m.Get("MyConstraint", null) == instance.MyConstraint);
    

    【讨论】:

    • 我不确定我是否理解您的答案... :( 我知道基于属性值的条件绑定可能并不理想,但我无法控制对象创建,因为创建是受控制的by ASP.NET. 我在我的问题中谈论的枚举用于定义要显示的数据类型(实体)。根据枚举上的选择,需要注入一个模板和一个查询数据库的对象。枚举只会使用控件从 aspx 文件中设置。即使注入正确的工厂,我不需要知道那个枚举的值吗?
    • 添加了一个例子。注意我没有对代码进行语法检查,所以它可能无法编译。但它应该解释我之前写的内容。
    • 谢谢,很好。我最终使用了与您的第一个示例有些不同的东西,但我不知道/意识到您可以使用 ninject 注入 Func 对象。
    【解决方案2】:

    我正在使用的(现在使用 Ninject 3)有点不同,但它对我有用。 我创建了一组依赖项,让他们决定是否接受处理请求。例如,如果我有这种情况

    public enum FileFormat
    {
        Pdf,
        Word,
        Excel,
        Text,
        Tex,
        Html
    }
    
    public interface IFileWriter
    {
        bool Supports(FileFormat format)
    
        ...
    }
    
    public class FileProcessor
    {
        FileProcessor(IFileWriter[] writers)
        {
            // build a dictionary with writers accepting different formats 
            // and choose them when needed
        }
    }
    
    public class MyModule : NinjectModule
    {
         public override void Load()
         {
             ...
    
             Bind<IFileWriter>().To<PdfFileWriter>();
             Bind<IFileWriter>().To<WordFileWriter>();
             Bind<IFileWriter>().To<TexFileWriter>();
             Bind<IFileWriter>().To<TextFileWriter>();
             Bind<IFileWriter>().To<HtmlFileWriter>();
         }
    }
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多