3

I am trying to build a framework of objects where the main actors can be interchanged freely. At the moment I've done this by creating an abstract base class that all of my actors can be derived from. A key reason for using an abstract class over an interface was there there is a very small bit of common code that all of the derived classes should be using.

My goal is to make a system that can be easily extended by other developers (one day) that shares some common logic and the derived objects can be seamlessly interchanged.

I've had a few issues with the way I've designed the system. One being that it hasn't been easy to test consumers of my framework. But the one I'm most interested in solving at the moment is that some of the derived classes need to implement IDisposable because they contain objects which need to be disposed.

The best solution I've found at the moment is to have the abstract class implement IDisposable even though it doesn't require it and some of the other derived classes don't either. I realize I have some fundamental issues with the way I've modelled my objects and I'm trying to work out the best way to do it.

However, I'm still curious what is the best way to conditionally implement IDisposable? Or do I just have a serious design issue that needs to get sorted out instead and I'm trying to solve a problem that will no longer be an issue with the correct model?

asked Apr 19, 2016 at 13:38
2
  • Shared common code or shared common state? You can do the former with extension methods on an interface Commented Apr 19, 2016 at 13:41
  • You don't need to conditionally implement IDisposable. Always implement it in the abstract base class (or interface) and have the abstract base class (or whoever needs to) provide a Dispose that does nothing. Commented Apr 19, 2016 at 14:57

2 Answers 2

4

I don't think it's unreasonable for your abstract base class to provide an empty implementation of the IDisposable interface, and for subclasses to implement their own implementation as required. That seems to me a commonly used and understood pattern.

answered Apr 19, 2016 at 13:41
2
  • Downvoted why ? Commented Apr 19, 2016 at 20:13
  • Because it's much preferable to have a design that doesn't require you to implement interfaces that you're not really implementing. Commented Apr 19, 2016 at 23:52
2

Brian Agnew's suggestion is very much applicable, but I'd like to point out something else:

I get the feeling that maybe the actors (the plugged-in behavior you mentioend) on your model are carrying two very different responsibilities. Alternatively, you could design your framework to have a separate registration mechanism, exclusively for disposable resources, in the same way you allow the actors to be registered. Just to clarify, let's say you currently have the following class:

class MyFramework {
 public void RegisterActor(Actor actor) {
 ...
 }
}

And that the Actor base-class (or interface) looks like this:

abstract class Actor : IDispoable {
 ...
}

You could break apart the notions of actors and disposable resources by changing the usage of your framework to allow both to be registered separately, like so:

class MyFramework {
 public void RegisterActor(Actor actor) {
 ...
 }
 public void RegisterResource(IDisposable resource) {
 ...
 }
}

This would allow you to break the IDisposable interface out of your actor model, while still giving the option to the subclass implementer to have both implementations in the same object, if that makes sense, like so:

class SomeActorImplementation : Actor, IDisposable {
 ...
}

With that, the same object can be sent to both RegisterActor and RegisterResource methods of the framework object, but it will have no knowledge of it.

answered Apr 19, 2016 at 14:04
1
  • This. I have only very rarely ever needed to actually implement IDisposable and given proper thought and attention, I bet I wouldn't have needed to for those either. A Func<T> or factory class can go a long way. Commented Apr 19, 2016 at 16:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.