Я новичок в внедрении Dependency Injection, поэтому, пытаясь реализовать его в моих проектах net core 3.0, я столкнулся со сценарием, в котором мне нужно несколько экземпляров одной службы, зарегистрированной в моем поставщике услуг. В качестве обходного пути я прибег к внедрению самого IServiceProvider
и простому вызову GetRequiredService<T>
(служб с временной областью) несколько раз. Это работает, но, похоже, это анти-паттерн, и я не уверен, как я должен это делать правильно.
Часть проблемы при исследовании этого вопроса заключается в настойчивости в каждом ответе, что Потребность в нескольких экземплярах одного класса сама по себе является запахом кода, но в качестве примера, скажем, я даю инструкции духовке для автоматизации процесса выпечки. Пользователь определит температуру и время для каждого рецепта в представлении, затем представление вернет List<string>
, который представляет этот список шагов в контроллер. Примерный список шагов может выглядеть так:
//Bake for 500 degrees Fahrenheit for 30 minutes, then 225F for another 90
["500F,30","225F,90"]
Затем мне нужно будет преобразовать его в List<CookingStep>
в контроллере, чтобы добавить к моему Recipe
объекту. Я делал что-то вроде этого:
IOven Oven;
IRecipe newRecipe;
IServiceProvider sp;
//public OvenController... (constructor with dependencies injected here)
public async Task<IActionResult> BakeSomething(List<string> steps)
{
foreach(string s in steps)
{
IRecipeStep recipeStep = sp.GetRequiredService<IRecipeStep>();
recipeStep.ParseTimeAndTemperatureFromString(s);
newRecipe.Steps.Add(recipeStep);
}
await Oven.Bake(newRecipe);
return View("RecipeComplete",newRecipe);
}
Но на самом деле это не инверсия управления, и это не делает код более тестируемым, поэтому, изучая лучшие практики, я мог бы сделать фабрику шаблон, но я не уверен, как это поможет сделать что-либо, кроме как похоронить окончательный экземпляр в другом классе.
Таким образом, я могу создать фабрику, даже обобщенную c, но это (по общему признанию, чрезмерно simpisti c пример) действительно лучше, чем приведенный выше шаблон поиска служб?
IOven Oven;
IRecipe newRecipe;
IRecipeStepFactory rsFactory;
//public OvenController... (constructor with dependencies injected here)
public async Task<IActionResult> BakeSomething(List<string> steps)
{
foreach(string s in steps)
{
IRecipeStep recipeStep = rsFactory.NewStepFromString(s);
newRecipe.Steps.Add(recipeStep);
}
await Oven.Bake(newRecipe);
return View("RecipeComplete",newRecipe);
}
public class RecipeStepFactory : IRecipeStepFactory
{
public IRecipeStep NewStepFromString(string s)
{
RecipeStep recipeStep = new RecipeStep();
recipeStep.ParseTimeAndTemperatureFromString(s);
return recipeStep;
}
}
(заранее прошу прощения за любые проблемы с изложением или содержанием моего вопроса, это первый раз, когда мне пришлось задать свой вопрос)