【问题标题】:How can I make the parents class aware of changes in the injected class如何让父类知道注入类的变化
【发布时间】:2013-06-08 17:20:54
【问题描述】:

我有两个班 A 和 B。

我将 B 注入 A (Dependency Injection)。

现在我想了解 B 类中的属性何时发生变化。

在不违反原则和模式的情况下,最好的做法是什么?

我应该使用EventHandlers吗?

【问题讨论】:

  • 我不认为“依赖注入”是描述你在说什么的正确术语。
  • 您是在询问策略模式
  • 我认为依赖注入不能用于有状态对象。尽管有时需要它,但通常该状态对象是作为变量传递的,而不是注入的。有关信息,请参阅此stackoverflow.com/questions/4676477/… 问题。

标签: c# design-patterns dependency-injection


【解决方案1】:

最常见的方式是实现INotifyPropertyChanged Interface

接口定义了一个成员:

event PropertyChangedEventHandler PropertyChanged

这样使用:

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

如果您使用 .Net 4.5,则可以使用 CallerMemberNameAttribute,因此您不必手动(或通过其他方式)指定属性名称:

// This method is called by the Set accessor of each property. 
// The CallerMemberName attribute that is applied to the optional propertyName 
// parameter causes the property name of the caller to be substituted as an argument. 
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

以上代码的来源是我链接到的文档。

如果你使用.Net 4.0或更早的版本,你仍然可以使用强类型属性名来代替手动输入字符串,但是你需要实现一个方法like this,然后你可以使用表达式来调用它:

OnPropertyChanged(() => this.SomeProperty);

【讨论】:

  • 谢谢。 PropertyChangedEventHandler 应该在 A 类还是 B 类中定义?第二个问题是不是完全违反了原则?
  • B 类应该实现 INotifyPropertyChanged 接口(并因此实现 PropertyChanged 事件)。 A 类应附加到 B 类公开的 PropertyChanged 事件。
  • 总的来说,这个想法是好的。但是,我强烈反对在代码中使用 INotifyPropertyChanged。该接口属于“视图模型”层。在“模型”层中,您应该更具体地命名您的事件,即SomethingSpecificHappened。原因是该接口用于特定目的:发生运行时成员发现的数据绑定。 “只有”一个属性发生了变化。模型中的更改(在语义上)比属性更改更重要。属性变化只是一个后果......
  • @dzendras: “接口属于‘视图模型’层”“接口用于特定目的:数据绑定”:不,它不是,它只是一个你可以在适当的地方使用的接口(但数据绑定到视图模型确实是一个非常常见的用例)。 “模型中的更改(在语义上)比属性更改重要得多。”:这并不意味着您不应该使用 INotifyPropertyChanged。 (但是,在某些情况下,自定义界面或其他模式更可取。例如,如果您需要“属性 ies 已更改”事件)。
  • 你是对的,但我坚持认为在模型层中使用 INotifyPropertyChanged 会使代码膨胀。想象一个应用程序的结构不“只是”这样:UI -> ViewModel/Controller -> Business Logic -> Repository/WCF。相反,模型包含状态,由多个服务(可能使用线程)组成,并且您将有意义的事件替换为 INPC。想象一下客户端代码看起来有多糟糕。如果 propertyName == "Foo" DoSth(); else if propertyName == "Bar" DoSthElse();等等。太糟糕了。
【解决方案2】:

我认为使用 INotifyPropertyChanged 接口是一种便于 UI 编程(wpf-MVVM)的事件处理,以这种方式使用事件处理违反了两个原则:

1) 简单性。如果你有很多类,你的代码在一段时间后就会变成事件的spageti。

2)conserns分离,事件操作的职责可以分配给另一个特定的类。

如果你关心原则,你最好看看观察者模式,它定义了对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖者都会得到通知并自动更新。

另外,如果你有很多依赖对象,我的建议是你最好给我们一个 IOC 容器(例如:spring.net 或 prism,...)来进行依赖注入,因此,您当然可以利用容器的解决方案,例如在 Prism 中,您可以从 EventAggregator 中受益,或者 spring.net 有一个 xml 基础事件聚合器

【讨论】:

  • 我完全不同意。没有说 A 是否将 B 视为普通 B 或接口。如果有接口,您的第一点无效。如果不是观察者模式的特定实现,那么 .NET 中的事件是什么?在这种特殊情况下,您的判断过于苛刻。但是,您的动机很好,您的建议听起来不错。
  • 是的,我同意你的看法。谢谢我改变了它。复杂性呢?我认为在流行的事件处理框架中存在灵魂是为了减少它的缺点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2019-05-05
  • 1970-01-01
  • 2017-09-30
  • 2011-09-10
  • 2011-03-31
相关资源
最近更新 更多