Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建易失性接口实例-依赖项注入与服务定位器_C#_Asp.net Mvc_Dependency Injection_Service Locator - Fatal编程技术网

C# 创建易失性接口实例-依赖项注入与服务定位器

C# 创建易失性接口实例-依赖项注入与服务定位器,c#,asp.net-mvc,dependency-injection,service-locator,C#,Asp.net Mvc,Dependency Injection,Service Locator,问题是我有三层项目:DataAccessdll和Presentationdll依赖于Logicdll。在逻辑中,我定义了接口odIRepository、IMyIdentityUser等。在DataAccess中,我使用Microsoft Identity framework向MyIdentityUser注册新用户,MyIdentityUser继承了IdentityUser和IMyIdentityUser接口。我也在使用IoC容器。 假设我有一个名为“Register”的表示层(MVC)方法,该方

问题是我有三层项目:
DataAccess
dll和
Presentation
dll依赖于
Logic
dll。在逻辑中,我定义了接口od
IRepository、IMyIdentityUser
等。在DataAccess中,我使用Microsoft Identity framework向MyIdentityUser注册新用户,MyIdentityUser继承了
IdentityUser
IMyIdentityUser
接口。我也在使用IoC容器。 假设我有一个名为“
Register
”的表示层(MVC)方法,该方法带有参数“
RegisterViewModel
”,该参数将注册逻辑委托给
logic
dll中的某个类

  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);
    }
并将其作为参数传递给控制器构造函数(可能在facade参数中包含另一个逻辑连接的参数),但我不确定这一点,因为它通常与传递lonely
IMyIdentityUser
相同。 有没有更好的办法

另外,我不想在构造函数中包含参数IMyIdentityUser和 每次启动时强制IoC容器创建新的用户实例 创建MVC控制器

你的前提从零开始就错了

  • MVC控制器不是有状态的。每个请求都实例化一个MVC控制器(如果您阅读这里的#2点,您可能会认为,如果您实现了,您可以更改此默认行为!)
  • IoC容器不一定创建给定注入依赖项的新实例:它取决于组件生命周期。例如,Castle Windsor将为您提供瞬态、单例、每个请求、每个线程、池和其他生命周期。Transient将是唯一的选择,它肯定会创建给定注入依赖项的实例
  • 因此,基于您错误的假设,我肯定会在需要依赖项的任何地方使用构造函数注入。或者属性注入,但这不是实现依赖项注入时的首选,因为通常属性注入是可选的

    另一方面,构造注入应该是一种方式,因为在可测试性方面,每段代码都将独立于其他代码(较少耦合):您可以自动或手动实例化给定的类,也可以自动或手动提供其依赖项

    另外,我不想在构造函数中包含参数IMyIdentityUser和 每次启动时强制IoC容器创建新的用户实例 创建MVC控制器

    你的前提从零开始就错了

  • MVC控制器不是有状态的。每个请求都实例化一个MVC控制器(如果您阅读这里的#2点,您可能会认为,如果您实现了,您可以更改此默认行为!)
  • IoC容器不一定创建给定注入依赖项的新实例:它取决于组件生命周期。例如,Castle Windsor将为您提供瞬态、单例、每个请求、每个线程、池和其他生命周期。Transient将是唯一的选择,它肯定会创建给定注入依赖项的实例
  • 因此,基于您错误的假设,我肯定会在需要依赖项的任何地方使用构造函数注入。或者属性注入,但这不是实现依赖项注入时的首选,因为通常属性注入是可选的


    另一方面,构造注入应该是一种方式,因为在可测试性方面,每段代码都将独立于其他代码(较少耦合):您可以自动或手动实例化给定类,也可以自动或手动提供其依赖项。

    a.D.1。是的,它们不是有状态的。所以,如果控制器有4种方法,并且其中只有一种方法需要构造函数中的新用户,那么每次我们使用剩余的3种方法时,让IoC容器创建这个用户将是浪费资源的——假设用户具有瞬态或每个请求的生命周期。但它不可能是单线程或每线程,池化也没有多大意义。最好只为Register方法创建此用户。当然,新用户是非常轻的对象,不会对应用程序性能产生太大影响,但我仍然想知道如何正确地做到这一点。@BartekWójcik好吧,在给我的答案添加更新之前,让我们在这里讨论一下这个问题。@BartekWójcik实际上是一个
    IControllerActivator
    实现,可以实现一些逻辑来确定是哪个方法应该激活某些依赖项。使用你的国际奥委会框架和一些努力,你应该能够让这项工作。好的,现在我明白了。谢谢。1.是的,它们不是有状态的。所以,如果控制器有4种方法,并且其中只有一种方法需要构造函数中的新用户,那么每次我们使用剩余的3种方法时,让IoC容器创建这个用户将是浪费资源的——假设用户具有瞬态或每个请求的生命周期。但它不可能是单线程或每线程,池化也没有多大意义。最好只为Register方法创建此用户。当然,新用户是非常轻的对象,不会对应用程序性能产生太大影响,但我仍然想知道如何正确地做到这一点。@BartekWójcik好吧,在给我的答案添加更新之前,让我们在这里讨论一下这个问题。@BartekWójcik实际上是一个
    IControllerActivator
    实现,可以实现一些逻辑来确定是哪个方法应该激活某些依赖项。使用你的国际奥委会框架和一些努力,你应该能够让这项工作。好的,现在我明白了。谢谢
    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
    }