views:

46

answers:

1

Say I have a basic interface like the following:

public interface IObjectProvider
{
    IEnumerable<IObject> GetObjects();
}

The object source is some backing store that might be updated, and the implementation of this interface takes care of using that backing store. Now I'd like consumers of this interface to be able to take actions whenever the collection of objects provided by this interface changes. How would you restructure this interface to provide this ability? I'd like the result to be usable for many "provider" interfaces in the application for good design consistency.

Example: The following provides this feature in a concise and understandable way, but adds significant coupling (including references to the WPF assemblies in pre-.NET 4.0 code). Should I just use this since we know that once code goes to .NET 4.0 it will automatically be "lighter"?

public interface IObjectProvider
{
    ReadOnlyObservableCollection<IObject> Objects
    {
        get;
    }
}

Edit 1:

Based on Reed's answer, I'm leaning towards leaving the IObjectProvider interface unchanged for the following reasons:

  • This is a new application, so the design can be documented early and followed with consistency throughout.
  • Declare that for all providers, if the provider supports notifications that the provided collection changed, then the value returned by GetObjects() will necessarily implement INotifyCollectionChanged.

There are two other cases raised by this that I still need to account for in my design:

  • The provided collection never changes.
  • The provided collection might change, but the client would need to poll if it wanted the updates. Could I just make the claim that this case won't exist in the application (and is that a good idea)?
+4  A: 

You could always use the interfaces for this, such as INotifyPropertyChanged and INotifyCollectionChanged.

This would allow you to use a custom collection, and standard interfaces, without taking references to WPF.

Reed Copsey
Would you leave the `IObjectProvider` interface as-is on the assumption that 1) the client can check if it implements `INotifyCollectionChanged` and 2) the person writing the client will safely infer that *if* the provider provides such notifications then the object returned by `GetObjects()` *will* implement that interface for that purpose? On a side note, `INotifyCollectionChanged` is declared in WindowsBase.dll pre-4.0, but moved to System.dll for 4.0.
280Z28
I've written code where I (as the client) check for that interface explicitly- it works fairly well. Unfortunately, there isn't an ICollection<T> interface that includes INCC as well :(
Reed Copsey
280Z28
Check my edit in the question :)
280Z28
@280Z28: I wouldn't necessarily change anything, for this, other than maybe have the provider return ICollection<T> instead of IEnumerable<T> (since it's always a collection). You could always add an overload to return an INotifyCollectionChanged reference, just to demonstrate that the providers provde that...
Reed Copsey