Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Логика сохранения настроек в XML, где есть делегат

414
21 августа 2012 года
CassandraDied
763 / / 24.05.2012
Доброго.
Есть один объект, который смотрит, какие файлы появились в определённом каталоге.
При инициализации объекта, его делегату присваивается(?) функция, находящаяся вне этого объекта, которая будет обрабатывать список новых файлов в каталоге.
Ну и имя каталога тоже передаётся при инициализации.
Приложение завершается и объекту нужно запомнить, куда смотреть нужно, чтобы смотреть туда же после начала работы приложения и, чтобы заново не производить его инициализацию. Имя каталога схоронить легко, а что делать с делегатом?
Какие могут быть идеи?
По-моему, всё-таки лучше перенести сохранение и восстановления списка каталогов во "внешний" объект, а потом заново инициализировать наблюдателя- это сделает работу приложения более понятной и простой в изменении.
Но этим сохранением вроде бы как должен заниматься сам наблюдающий объект по логике, его же всё-таки настройки.
341
25 августа 2012 года
Der Meister
874 / / 21.12.2007
Объект никому ничего не должен. Всё зависит от объектов, с которыми он взаимодействует. Можно, например, сделать так:
Код:
class Settings {
    string _directory;
   
    public Observer CreateObserver() {
        return new Observer(_directory);
    }
   
    pubic void Save(string path) {
        // ...
    }
   
    public static Settings Load(string path) {
        // ...
    }
}
Что там у вас за делегат? Он ссылается на статичный метод, или на метод экземпляра? Можно сериализовать Linq.Expressions, можно заюзать отражение или ещё что нибудь - хз, вы как-то чересчур мутно описываете задачу, надо более конкретно.
414
25 августа 2012 года
CassandraDied
763 / / 24.05.2012
На нестатический метод public static Method(String) формы(или не формы, а класса ядра)
Конкретней уже некуда. Есть форма и есть объект, который отслеживает изменения в каталогах. Через форму задаётся, какие каталоги отслеживать. Объект, который этим занимается, создаёт в себе словарь, где хранятся структуры всех наблюдаемых каталогов, вернее, структуры, которые хранят метаданные - имя каталога, его FileSystemWatcher и делегаты на методы формы, которые буду что-то делать с именем нового файла в каталоге.
Может быть, неправильно, что форма будет обрабатывать данные о новых или удалённых файлах и нужно ввести ещё какой-нибудь объект-ядро для этого, а форму оставить взаимодействовать только с БД, где сразу будет готовая информация о файлах.
341
26 августа 2012 года
Der Meister
874 / / 21.12.2007
Код:
class Database {
    readonly ICollection<DirectoryEntry> _entries = new List<DirectoryEntry>();

    public ICollection<DirectoryEntry> Entries {
        get { return _entries; }
    }

    public Observer CreateObserver(object obj) {
        var observer = new Observer();

        foreach (var entry in _entries) {
            entry.Register(observer, obj);
        }

        return observer;
    }
}

class DirectoryEntry {
    public string Path { get; set; }
    public string MethodName { get; set; }

    public void Register(Observer observer, object instance) {
        var method = new Method(instance, MethodName);
        observer.Add(Path, method);
    }

    public void Unregister(Observer observer) {
        observer.Remove(Path);
    }
}

class Observer : Disposable {
    readonly ICollection<ObservableDirectory> _directories = new List<ObservableDirectory>();
   
    public void Add(string path, Method method) {
        _directories.Add(new ObservableDirectory(path, method));
    }

    public void Remove(string path) {
        var item = _directories.SingleOrDefault(directory => directory.IsMatch(path));
        if (item != null) {
            _directories.Remove(item);
        }
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            foreach (var item in _directories) {
                item.Dispose();
            }
        }
    }
}

sealed class ObservableDirectory : Disposable {
    readonly string _path;
    readonly FileSystemWatcher _watcher;
    readonly Method _method;

    public ObservableDirectory(string path, Method method) {
        _path = path;
        _watcher = new FileSystemWatcher(path);
        _method = method;

        _watcher.Created += OnFileCreated;
    }

    public bool IsMatch(string path) {
        return path.ToUpper() == _path.ToUpper();
    }

    string GetNewName(string name) {
        return _method.Invoke<string>(name);
    }

    void OnFileCreated(object sender, FileSystemEventArgs e) {
        var name = GetNewName(e.Name);
        File.Move(e.FullPath, name);
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            _watcher.Dispose();
        }
    }
}

class Method {
    readonly object _instance;
    readonly MethodInfo _method_info;

    public Method(object instance, string name) {
        _instance = instance;

        const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        _method_info = instance.GetType().GetMethod(name, flags);
    }

    public T Invoke<T>(params object[] args) {
        try {
            return (T)_method_info.Invoke(_instance, args);
        }
        catch (TargetInvocationException ex) {
            throw ex.InnerException;
        }
    }
}

abstract class Disposable : IDisposable {
    bool _disposed;

    protected abstract void Dispose(bool disposing);

    public void Dispose() {
        if (_disposed) {
            return;
        }

        _disposed = true;
       
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public ~Disposable() {
        if (!_disposed) {
            Dispose(false);
        }
    }
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог