Не уверен, правильно ли я вас понял, но я думаю, что вы, возможно, слишком усложняете вещи.Для начала, убедитесь, что вы разработали свой код независимо от какой-либо фабрики или Dependency Injection, фреймворка или структуры компоновки.
Для начала давайте посмотрим, как должен выглядеть ваш вызывающий код, это то, что вы сказали:
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID);
Вы не обязаны соглашаться с моим выбором именования ниже, но это указывает на то, что я понимаю из вашего кода, вы можете сказать мне, если я ошибаюсь.Теперь я чувствую, что вызов будет проще, как это:
RepositoryFactory.New<IRepository<Customer>>().Get(myId);
RepositoryFactory.New<IWebServiceLogRepository>().GetOpenLogs(myId);
Строка 1: Поскольку здесь указан тип IRepository, ясно, что является возвращаемым типом и типом Tпредназначен для базового IRepository.
Строка 2: Тип возврата здесь с фабрики - IWebServiceLogRepository.Здесь вам не нужно указывать тип сущности, ваш интерфейс логически уже реализует IRepository.Нет необходимости указывать это снова.
Таким образом, ваш интерфейс для них будет выглядеть так:
public interface IRepository<T>
{
T Get(object Id);
T Save(T object);
}
public interface IWebServiceLogRepository: IRepository<WebServiceLog>
{
List<WebServiceLog> GetOpenLogs(object Id);
}
Теперь я думаю, что реализации и код фабрики для этого будут проще, поскольку только фабрикадолжен знать об одном типе.В строке 1 типом является IRepository, а в строке 2 IWebServiceLogRepository.
Попробуйте это и попробуйте переписать свой код, чтобы просто найти классы, реализующие эти типы, и создать их экземпляры.
Наконец, вС точки зрения MEF, вы можете продолжать использовать это, но Castle Windsor действительно сделает все намного проще для вас, так как позволит вам сконцентрироваться на вашей архитектуре и дизайне кода, и его очень очень просто использовать.Вы только когда-либо ссылались на Castle в коде запуска своего приложения.Остальная часть вашего кода просто разработана с использованием шаблона внедрения зависимостей, который не зависит от фреймворка.
Если что-то из этого не ясно, дайте мне знать, если вы хотите, чтобы я обновил этот ответ с помощью реализациикод ваших репозиториев тоже.
ОБНОВЛЕНИЕ
и вот код, который разрешает реализации.Вы делали это немного сложнее для себя, не используя класс Activator.
Если вы используете Activator и используете только один параметр Generic, как я делал в методе ниже, с вами все будет в порядке.Обратите внимание, что код немного грубоват, но вы поняли:
public static T GetThing<T>()
{
List<Type> assemblyTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes()).ToList();
Type interfaceType = typeof(T);
if(interfaceType.IsGenericType)
{
var gens = interfaceType.GetGenericArguments();
List<Type> narrowed = assemblyTypes.Where(p => p.IsGenericType && !p.IsInterface).ToList();
var implementations = new List<Type>();
narrowed.ForEach(t=>
{
try
{
var imp = t.MakeGenericType(gens);
if(interfaceType.IsAssignableFrom(imp))
{
implementations.Add(imp);
}
}catch
{
}
});
return (T)Activator.CreateInstance(implementations.First());
}
else
{
List<Type> implementations = assemblyTypes.Where(p => interfaceType.IsAssignableFrom(p) && !p.IsInterface).ToList();
return (T)Activator.CreateInstance(implementations.First());
}
}