Я уже пару дней думаю о запуске нового проекта в C # .NET (4.0RC). Конечным результатом проекта будет библиотека классов, состоящая из того, что я пока называю «ProviderFactory», пары интерфейсов (или абстрактных классов) и «ProviderType» по умолчанию или двух.
Прежде всего мне может понадобиться / принять решение изменить наименование моих классов, чтобы они не конфликтовали с тем, что уже есть в .NET. Во-вторых, есть хороший шанс, что то, что я здесь описываю, уже существует (оно может быть даже внутри .NET без моего ведома), так что в этом случае будет полезна отдельная ссылка на этот проект или учебник.
Функциональность, о которой я думаю, это не просто фабрика, которая может предоставить мне простого провайдера, но она должна быть способна генерировать любого типа провайдера. Я хочу иметь возможность написать что-то вроде этого:
BlogProvider bp = ProviderFactory.GetProvider<BlogProvider>();
и должен возвращать текущий выбранный BlogProvider, или ноль, если его нет. Также я хочу иметь возможность предоставить список всех доступных провайдеров одного типа, например,
string[] blogproviders = ProviderFactory.GetRegisteredProviders<BlogProvider>();
и должен возвращать массив строк с блог-провайдерами (например, «ODBCBlogProvider», «XMLBlogProvider» и т. Д.). Мне также нужно иметь возможность установить текущий поставщик, например, так:
ProviderFactory.SetCurrentProvider<BlogProvider>("ODBCBlogProvider");
Это должно сделать текущий BlogProvider ODBCBlogProvider, так что в следующий раз, когда я вызову ProviderFactory.GetProvider (), он должен вернуть экземпляр ODBCBlogProvider (что по причине необходимости расширить базовый класс BlogProvider).
Кроме того, каждый ProviderType (или ProviderBase, если хотите) должен иметь ProviderTypeName (BlogProvider) и ProviderTypeDisplayName («Блог» или «Блог-провайдер»), который уникален для этого ProviderType и каждого провайдера, расширяющего потребности этого провайдера. иметь ProviderName (ODBCBlogProvider) и ProviderDisplayName («ODBC» или «блог ODBC» и т. д.). ProviderName и ProviderTypeName могут просто для простоты быть именами классов, полученными при отражении.
Это, вероятно, означает, что мне нужен интерфейс для ProviderBase, что-то вроде этого:
public interface ProviderBase
{
string ProviderName { get; } // The display-name.
string Description { get; } // A description of the provider type, like "This provides you with a blog."
}
А для BlogProvider мне нужно создать абстрактный класс, который реализует эти два члена и создает методы для переопределения реальных BlogProvider.
public abstract class BlogProvider : ProviderBase
{
public string ProviderName
{
get { return "Blog"; }
}
public string Description
{
get { return "This provides you with a blog."; }
}
public abstract int GetPostCount();
}
Затем где-то в моем коде мне нужно было выполнить что-то вроде
ProviderFactory.RegisterProviderType(typeof(BlogProvider));
или, что еще лучше, можно использовать такие атрибуты:
[Provider("Blog", "This provides you with a blog.")]
public interface BlogProvider
{
int GetPostCount();
}
Я не вижу необходимости использовать абстрактный класс с этим подходом, потому что ни один из членов не должен быть установлен в базовом классе. Также исчезла необходимость в ProviderBase-интерфейсе. Идеально было бы, если бы ProviderFactory мог просто найти все классы / интерфейсы, содержащие ProviderAttribute, а ODBCBlogProvider просто должен был бы реализовать BlogProvider, но я не уверен, как мне это сделать, особенно когда это требование Типы провайдеров и провайдеров могут приходить для внешних сборок.
Другое требование к ProviderFactory - это то, что он должен работать как в среде без состояния, так и в среде, где он поддерживается, поэтому он должен иметь возможность сохранять настройки в некоторый файл конфигурации / поток / базу данных (что-то подобное). , на самом деле не имеет значения) при изменении и загрузке из этого при инициализации, но это должно быть необязательным. Таким образом, он также будет работать в Интернете (наличие блога на собственной машине не имеет большого смысла).
Еще одно требование заключается в том, что поставщики могут требовать других поставщиков для работы. Например, AudiEngine может работать только с AudiCar, однако AudiCar может отлично работать с BmwEngine.
Кроме того (и я пока не уверен, куда это поместить, может быть, необязательный атрибут в самом классе провайдера) у каждого провайдера должна быть опция singleton или нет.
Это все, что я могу думать сейчас.Любая информация о том, как это должно быть реализовано или есть ли уже реализация, будет очень признательна, и все может быть изменено, потому что я еще не написал никакого кода, это все, о чем я думал сейчас.