Я экспериментировал с использованием именованных делегатов вместо интерфейсов с одним методом. Это имеет некоторые преимущества для размер кода, от которого мы можем перейти (некоторые разрывы строк удалены, чтобы не преувеличивать регистр):
public interface IProductSource
{
IEnumerable<Product> GetProducts();
}
public class DataContextProductSource : IProductSource
{
private readonly DataContext _DataContext;
public DataContextProductSource(DataContext dataContext)
{
if (dataContext == null) throw new ArgumentNullException("dataContext");
_DataContext = dataContext;
}
public IEnumerable<Product> GetProducts()
{
return _DataContext.Products.AsEnumerable();
}
}
до:
public delegate IEnumerable<Product> DGetProducts();
public static class DataContextFunctions
{
public DGetProducts GetProducts(DataContext dataContext)
{
if (dataContext == null) throw new ArgumentNullException("dataContext");
return () => dataContext.Products.AsEnumerable();
}
}
Это в основном пользуется преимуществом того факта, что как только вы продвинетесь достаточно далеко с внедрением зависимостей, много классы становятся не более чем замыканиями. Эти классы могут быть заменены функциями, возвращающими лямбда-выражения. Целые наборы связанных функций (которые не должны инкапсулировать какое-либо изменяемое состояние, но были бы выражены с использованием классов в «стандартной» инъекции зависимостей), затем можно объединить в статический класс (или «модуль» на языке VB).
Это все хорошо, но у меня возникли проблемы с поиском лучшего способа зарегистрировать эти статические методы в Castle Windsor. никакие зависимости не просты:
Component.For<DGetIntegers>().Instance(Integers.GetOneToTen)
Но наш DataContextFunctions.Get У продуктов сверху есть некоторые зависимости. Я нашел лучший способ зарегистрировать это:
Component.For<DGetProducts>().UsingFactoryMethod(
kernel => DataContextFunctions.GetProducts(kernel.Resolve<DataContext>())
Это может быть довольно многословным, и, очевидно, необходимость напрямую запрашивать ядро для каждого типа зависимости немного нарушает суть. Мне кажется, что вся статическая информация, которая может понадобиться контейнеру, доступна, поэтому это должно быть возможно.
Вопрос в том, есть ли у Castle Windsor (или любого другого контейнера) простой способ сделать это, чтобы Я пропустил, или возникают технические проблемы, или это просто слишком нишевый вариант использования, чтобы включать его?