Проблема заключается в том, что у меня есть проект из 3 слоев: DataAccess
dll и Presentation
dll зависит от Logic
dll. В логике я определил интерфейсы IRepository, IMyIdentityUser
и т. Д. В DataAccess я использую среду Microsoft Identity для регистрации новых пользователей с MyIdentityUser, которая наследует IdentityUser<Guid>
и IMyIdentityUser
. Я также использую контейнер IoC. Предположим, что у меня есть метод уровня представления (MVC), называемый «Register
» с аргументом «RegisterViewModel viewModel
», который делегирует регистрацию логики некоторому классу в dll Logic
.Создание волатильных экземпляров интерфейсов - инжекция зависимостей против локатора службы
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = MyCore.Resolve<IMyIdentityUser>(); //this is service locator
// antipattern and I want to get
// rid of this
user.UserName = model.Email;
user.Email = model.Email;
var userManager = _userManager;
var result = await userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var signInManager = _signInManager;
await signInManager.SignInAsync(user, false, false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
return View(model);
}
как вы видите Я использую локатор сервисов для получения нового экземпляра MyIdentityUser. Я не хочу создавать это как «new MyIdentityUser()
», потому что это заставляет меня использовать жесткую связь с dll DataAccess, где определен MyIdentityUser. Кроме того, я не хочу иметь в конструкторе параметр IMyIdentityUser
и принудительно использовать контейнер IoC для создания нового экземпляра пользователя каждый раз при создании MVC-контроллера. Я думаю, что я мог бы использовать какое-то абстрактную фабрику как
interface IMyIdentityUserFactory
{
IMyIdentityUser CreateNewUser(string name, string email); //any other better arguments?
// not like registerViewModel because
// this view model should be defined in presentation logic
}
и передать его в качестве аргумента в контроллер конструктора (может быть, в параметре фасадного с другими логически связанными параметрами), но я не уверен в этом, потому что это вообще такой же, как проходящий одинокий IMyIdentityUser
. Есть ли лучший способ сделать это?
A.D. 1. Да, они не имеют состояния.Поэтому, если у контроллера есть 4 метода, и только один из них нуждается в новом пользователе от конструктора, это будет пустой тратой ресурсов, чтобы позволить контейнеру IoC создавать этого пользователя каждый раз, когда мы используем оставшиеся 3 метода - при условии, что Пользователь имеет временный или индивидуальный жизненный цикл. Но он не может быть одноточечным или для потока, и объединение не имеет большого смысла. Лучше всего было бы создать этого пользователя ** только ** для метода Register. Конечно, новый Пользователь очень легкий объект и не будет сильно влиять на производительность приложения, но все же я хотел бы знать, как это сделать должным образом. –
@ BartekWójcik Я собираюсь ответить вам на обновление! –
@ BartekWójcik Хорошо, давайте обсудим это здесь, прежде чем добавлять обновление к моему ответу. –