Я пытаюсь внедрить службу в мои контроллеры, но я хочу добавить другой экземпляр моей службы в зависимости от нескольких параметров. На самом деле для этой части он работает, я в состоянии это сделать.ASP.NET Ядро зависимостей инъекции: разрешена служба во время выполнения с использованием делегата Func
Я хочу загрузить конкретный экземпляр IRepository<Database>
на основе некоторой конфигурации, которую мы получаем из файла конфигурации и соблюдения правила DRY (не повторяйте себя).
У меня есть эти 2 класса:
public abstract class FooServicesProvider
{
public Func<IServiceProvider, IRepository<Database>> DatabaseRepository = provider =>
{
return null;
};
}
public class FooFileSystemServicesProvider : FooServicesProvider
{
public new Func<IServiceProvider, IRepository<Database>> DatabaseRepository = provider =>
{
//Specific code determining which database to use and create a new one if needed
//our databases are FOLDERS containing some files
//knowing how chosenDb.FullName is set is not important here
//[...]
var databaseRepository = new DatabaseFileSystemRepository(chosenDb.FullName);
databaseRepository.testProperty = "Foo value";
return databaseRepository;
};
}
Обратите внимание на новый ключевое слово используется для переопределения код моего Func. Это лучший способ, который я нашел из-за делегата Func, я очень ограничен, я не могу использовать его в интерфейсе и не переопределять его.
Сейчас в моем ConfigureServices метод Startup.cs У меня есть этот код
var fakeConfiguration = "File";
FooServicesProvider servicesProvider = null;
if(fakeConfiguration == "File")
{
servicesProvider = new FooFileSystemServicesProvider();
}
else
{
servicesProvider = new AnotherFooServicesProvider();
}
//Here is the tricky part
//This should call FooFileSystemServicesProvider.DatabaseRepository because of the "new" keyword, but it's NOT
services.AddScoped<IRepository<Database>>(servicesProvider.DatabaseRepository);
Моя проблема заключается в том, что нового ключевого слово игнорируется во время выполнения и казненный Func является один объявленным в мой базовый класс вместо полученного.
Если я сделаю это, что он работает
services.AddScoped<IRepository<Database>>((servicesProvider as FooFileSystemServicesProvider).DatabaseRepository);
Но я не хочу, чтобы бросить его, как я не могу знать, какой типа моего servicesProvider будет, наконец.
Я попытался получить тип моего servicesProvider и бросить его своим типом, но я получаю ошибку компилятора, потому что переменная Type и класс отличаются.
Итак, как я могу получить хороший Func, выполненный во время выполнения? Спасибо
Вам нужно будет создать «DatabaseRepository» базового класса «virtual» и использовать 'override' в производном типе. – Steven
Замените новое ключевое слово, переопределив в объявлении свойства делегата. Это работает ? –
, конечно, игнорируется ключевое слово 'new', потому что' new' только скрывает метод/свойство базовых классов и не заменяет и не отменяет его ... – Tseng