3

I have two classes A and B.

I inject B into A (Dependency Injection).

Now I want to understand when a property in the class B has changed.

What is the best practice to do that without violating the principles and patterns?

Shall I use EventHandlers?

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
Mehrdad Kamelzadeh
  • 1,764
  • 2
  • 21
  • 39
  • I don't think that "Dependency Injection" is the right term to describes what you're talking about. – SimpleVar Jun 08 '13 at 17:27
  • are you asking about strategy patterns – Charlie Jun 08 '13 at 17:39
  • 1
    I don't think dependency injection can be used with stateful objects. Eventhough it is sometimes needed, usually that state object is being passed as variable, not injected. Please refer to this http://stackoverflow.com/questions/4676477/ioc-dependency-injection-for-stateful-objects-not-global question for information. – Fendy Jun 10 '13 at 05:26

2 Answers2

3

The most common way is to implement the INotifyPropertyChanged Interface

The interface defines one single member:

event PropertyChangedEventHandler PropertyChanged

Used like this:

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

If you use .Net 4.5 you can make use of CallerMemberNameAttribute so you don't have to specify the name of the property manually (or by other means):

// 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));
    }
}

The source of the above code is the documentation I linked to.

If you use .Net 4.0 or earlier, you can still use strongly typed property names instead of typing strings manually, but you need to implement a method like this, and then you can call it using expressions:

OnPropertyChanged(() => this.SomeProperty);
Community
  • 1
  • 1
lightbricko
  • 2,649
  • 15
  • 21
  • thanks. The PropertyChangedEventHandler should be defined in class A or B? the second question is doesn't that violating the principles at all? – Mehrdad Kamelzadeh Jun 08 '13 at 17:36
  • Class B should implement the INotifyPropertyChanged Interface (and hence implement the PropertyChanged event). Class A should attach to the PropertyChanged event that class B exposes. – lightbricko Jun 08 '13 at 17:46
  • 1
    Generally speaking, the idea is good. However I would strongly disrecommend using INotifyPropertyChanged all over in the code. The interface belongs to the "view model" layer. In the "model" layer you should name your events more specific i.e. SomethingSpecificHappened. The reason for that is that the interface serves for specific purpose: data binding where runtime members discovery happens. There "only" a property changes. A change in a model is something far more important (semantically) than a property change. The property change is just a consequence... – dzendras Jun 09 '13 at 07:24
  • @dzendras: **"The interface belongs to the 'view model' layer"** and **"the interface serves for specific purpose: data binding"**: No it doesn't, it's just an interface that you use wherever appropriate (but it's true that data binding to view models is a very common use case). **"A change in a model is something far more important (semantically) than a property change."**: That doesn't mean you shouldn't use INotifyPropertyChanged. (However, there are certainly cases where a custom interface or a different pattern is preferable. One example is if you need a 'Propert **ies** Changed' event). – lightbricko Jun 09 '13 at 16:12
  • You're right, but I insist that using INotifyPropertyChanged in the model layer bloats the code. Imagine an application is structured not "just" like that: UI -> ViewModel/Controller -> Business Logic -> Repository/WCF. Instead, the Model contains state, consists of several services (potentially using threads) and you replace meaningful events with INPC. Imagine how badly the client code looks like. If propertyName == "Foo" DoSth(); else if propertyName == "Bar" DoSthElse(); etc. Just awful. – dzendras Jun 10 '13 at 17:37
  • @dzendras: Basically you're saying that for a complex architecture vanilla INPC is probably not good enough, and I agree with that - you might need something better than vanilla INPC. One approach is to not use it like you suggest. Another approach is to inherit PropertyChangedEventArgs to add some members (but that requires casting). I think I should add that I avoid using INPC too in non-simple cases, but I use it in simple cases. – lightbricko Jun 10 '13 at 19:12
0

I think using INotifyPropertyChanged Interface is kind of Event handling which is convenient for UI programming (wpf-MVVM) and using Event handling in this way violates two principles:

1) Simplicity.If you have lots of classes your code after a while would be spageti of events.

2) Seperation of conserns, the duty of events manipulating could be assigned to another specefic class.

If you are caring about principles,you are better have a look at Observer pattern whic defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Also ,if you have lots of dependent objects my suggestion is that you are better to us an IOC container(for example:spring.net or prism,...) for your dependency injections,as a result, you certainly could utilize the container's solutions, for example in Prism you could benefit from EventAggregator or spring.net has a xml base event aggregator

Masoud
  • 260
  • 2
  • 9
  • I don't agree at all. It wasn't said if A sees B as plain B or as an interface. If there's an interface your first point is invalid. And what are events in .NET if not a specific implementation of an observer pattern? Your judgment is far too harsh in this particular case. However, your motivation is good and your proposals sound well. – dzendras Jun 09 '13 at 07:17
  • Yes I agree with you. thank you I changed it.what about complexity? I think existense of soultions in popular fraworks for event handling is to reduce it's drawbacks – Masoud Jun 09 '13 at 07:48