I have the following interface
public interface IDocumentController : IController
{
bool Handles(string path);
DocumentView New(string fileName);
DocumentView Open(string path);
//...
string FilePath { get; set; }
}
I have an abstract base class for all IDocumentController
types that implements the interface.
public abstract class DocumentController : IDocumentController
{
private IUndoRedoManager undoRedoManager;
public virtual void UpdateDisplayName(IDocumentView view, bool isDirty)
{
if (isDirty)
{
if (!view.DisplayName.EndsWith("*"))
view.DisplayName += "*";
}
else
view.DisplayName = Path.GetFileName(FilePath);
}
public virtual void ActivateView(object sender, EventArgs e)
{
IDocumentView view = (IDocumentView)sender;
((Form)view).ShowIcon = true;
Log.Trace($"DocumentController.ActivateView(): " +
"View \"{view.DisplayName}\" activated");
}
public virtual void DeactivateView(object sender, EventArgs e)
{
IDocumentView view = (IDocumentView)sender;
((Form)view).ShowIcon = false;
Log.Trace($"DocumentController.DeactivateView(): " +
"View \"{view.DisplayName}\" deactivated");
}
public void FileChangedHandler(string p)
{
if (p.CompareNoCase(FilePath))
HasChangedOnDisk = true;
}
public abstract string DefaultExtension { get; }
public abstract IView View { get; }
public virtual bool Handles(string path)
{
string extension = Path.GetExtension(path);
if (!String.IsNullOrEmpty(extension))
{
if (FileTypes.SelectMany(ft => ft.FileExtensions)
.Any(e => e.CompareNoCase(extension)))
return true;
}
return false;
}
public abstract DocumentView New(string fileName);
public abstract DocumentView Open(string path);
//...
public abstract string FilePath { get; set; }
}
and a little bit more... This class contains common functionality for all documents. All is working fine, but I now want to introduce a file system watcher which gets hooked up for all IDocumentController
regardless of type whenever a file is opened. Of course Open
itself cannot be common as different document types required different opening methodology, so I want to "decorate" the overriden Open
method in each IDocumentController
class with the logic to setup the watcher. I am proposing I merely add a virtual
method
private FileSystemObserver observer;
public virtual void StartFileSystemObserver()
{
observer = new FileSystemObserver(Path.GetDirectoryName(FilePath), "*.*", false);
observer.FileChanged += FileChangedHandler;
observer.FileDeleted += FileChangedHandler;
observer.Start();
}
which will have to be used by all document controllers that wish to observe changes of the opened file . So in a derived concrete class say SpreadsheetDocument
I will have
public override DocumentView Open(string path)
{
// Open my document...
UpdateDisplayName((IDocumentView)View, false);
}
But this will mean all documents controllers inheriting from DocumentController
will have to remember to invoke StartFileSystemWatcher()
in their Open
method.
Is there a way (I am sure there is, but it has been a long day) to ensure that StartFileSystemObserver()
is always invoked after the Open
method is called for any derived DocumentController
?
IDocumentController
? \$\endgroup\$