如何设置控制器以便使用存储库参数调用构造函数

How to set up controller so constructor gets called with repository argument

读了一些烂书,我无法弄清楚在我接管的 C# MVC 项目中是什么导致控制器构造函数总是传递一个存储库参数。

  public partial class AdminController : ApiController
  {
    IDataRepository _repo;
    public AdminController(IDataRepository repo)
    {
      _repo = repo;
    }
  }

甚至其他 class 不是部分的也是这样写的。 我查看了它们继承自的 class(或接口)。 有任何想法吗? 提前致谢。

这是 Dependency Injection,在启动中查看类似

的内容
services.AddTransiant<IDataRepository, DataRepo>();

这告诉依赖注入容器用 DataRepo.

的实例实例化 IDataRepository

正如其他人所说,依赖注入。但更多细节:

.net framework 和.net core 处理方式不同

它根本没有内置在 .net 框架中。您需要检查 global.asax 文件以了解发生了什么。大多数时候它是通过 nuget 包完成的。有很多流行的,例如 autofaq、ninject、简单注入器等。您应该看到一些关于构建容器和注册服务的内容。

.net core 有自己的依赖注入框架,所以经常使用。尽管有时人们仍然使用 nuget 包来处理更复杂的事情。 .net 核心内容将在 Startup.cs 文件中。看看有没有类似 services.AddTransient 的地方。

这是可能的,尽管不太可能有人在您的项目中编写了自己的依赖注入框架。在那种情况下,您会寻找他们编写了 ControllerFactory 实现。

如果您无法从这里弄清楚,请将 global.asax 文件或 startup.cs 文件添加到您的问题中。

这称为依赖注入。

Asp.net 内核有一个内置的 DI 容器。但是对于旧的 Asp.net 项目,你应该添加一个库来使用它。我不知道你用的是哪个库,但我可以举一些常见的例子:

简单的注射器

https://simpleinjector.readthedocs.io/en/latest/aspnetintegration.html

// You'll need to include the following namespaces
using System.Web.Mvc;
using SimpleInjector;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;

// This is the Application_Start event from the Global.asax file.
protected void Application_Start(object sender, EventArgs e) {
    // Create the container as usual.
    var container = new Container();
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

    // Register your types, for instance:
    container.Register<IUserRepository, SqlUserRepository>(Lifestyle.Scoped);

    // This is an extension method from the integration package.
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

    container.Verify();

    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}

温莎城堡

https://gist.github.com/martinnormark/3128275

    public class ControllersInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(AllTypes.FromThisAssembly()
                .Pick().If(t => t.Name.EndsWith("Controller"))
                .Configure(configurer => configurer.Named(configurer.Implementation.Name))
                .LifestylePerWebRequest());
        }
    } 

Asp.net核心

https://docs.microsoft.com/tr-tr/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddScoped<IMyDependency, MyDependency>();
}