Alex Weitzer
Alex Weitzer

Reputation: 181

Pattern to extend classes without modifying them (or knowing implementation details) (c#)

I am modifying some code that sits between two established layers, and am having trouble figuring out what the best design is.

Currently the code calls a file access library, and returns an object to the caller. I need to extend the returned object to add some custom dispose functionality. I don't have access to the definitions of the passed objects (some are filestreams, for example)

It would save me a lot of work if I could create a child instance that behaves like a base instance, and can be created from a base instance, but that has some hidden extra functionality. Can this be done without knowing the implementation details of the base class?

In code form that looks a lot like this:

private class FileObjectWithDispose : FileObject, IDisposable
{//voidaction is a delegate, this is .net 2.0
    private VoidAction _disposeCallback;

public static FileObjectWithDispose wrapFile(FileObject unWrappedFile, VoidAction DisposeAction)
{//Implementation missing, this is the crux of what I don't know how to do
    FileObjectWithDispose wrappedFile = new FileObjectWithDispose(unWrappedFile);
    wrappedFile._disposeCallback = DisposeAction;
    return wrappedFile;
}

private FileObjectWithDispose()
    : base(null, null)//base class does not have a default constructor
{
    throw new NotImplementedException("FileObjectWithDispose is a wrapper class which is intended only to be cast from a filestream.");
}

private void Dispose()
{
    _disposeCallback();
    base.Dispose();
}

}

a sample call would look like this:

Connect(file, username, password, domain);
return FileObjectWithDispose.wrapFile(OpenFile(path), () => { Disconnect(file, username); });

The key difficulty I'm having is, if it's possible, how do I take a base class instance and create a decorated instance if the base class does not implement an interface that allows itself to be decorated? Any ideas how to accomplish this task?

Thanks!

Upvotes: 2

Views: 3503

Answers (2)

TheSilverBullet
TheSilverBullet

Reputation: 625

The decorator pattern is the way to go.

  1. Create an interface ICustomDisposeAction (an example name)
  2. Implement this interface with all those possible classes which on you would want to perform DisposeAction on.

    FileObjectWithDispose : FileObject, IDisposable, ICustomDisposeAction

  3. Create another class Decorator which also implements ICustomDisposeAction. Pass the original base class through the constructor of the decorator and then call the decorator's DisposeAction on it.

public class Decorator : ICustomDisposeAction
{
  public FileObject wrappedFile { get; set; } 
  public Decorator(FileObject unWrappedFile,...)
  {
    wrappedFile = unWrappedFile;
    //Do your custom dispose here
  }
} 
  1. In those situations which demands a custom way of disposing the object, create the decorator object and do the custom dispose!

Hope this helps.

Upvotes: 6

Frigik
Frigik

Reputation: 449

Try use Decorator pattern. This link can help.

Upvotes: 2

Related Questions