简体   繁体   中英

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

Having soured books, I can't figure out what in a C# MVC project I'm taking over causes the Controller constructors to always be passed a repository argument.

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

Even other classes who are NOT partials are written this way. I have looked at the class (or Interface) that these inherit from. Any ideas? Thanks in advance.

This is called dependency injection.

Asp.net core has a built-in DI container. But for old Asp.net projects, you should add a library to use this. I don't know which library you use, but I can give some common examples:

Simple Injector

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));
}

Castle Windsor

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 Core

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>();
}

This is Dependency Injection , have a look in startup for something like

services.AddTransiant<IDataRepository, DataRepo>();

This tells the dependency injection container to instantiate IDataRepository with an instance of DataRepo .

Like others have said, dependency injection. But some more details:

.net framework and .net core handle it differently.

It's not built in at all in the .net framework. You'll want to check you global.asax file to figure out whats going on. Most of the time its done through a nuget package. there are many popular ones like autofaq, ninject, simple injector etc. You should see some stuff about building a container and registering services.

.net core has its own dependency injection framework it ships with, so quite often that's used. Although sometimes people still use a nuget package for something more complex. The .net core stuff will be in the Startup.cs file. See if theres anything like services.AddTransient anywhere.

It's possible, though unlikely someone wrote there own dependency injection framework in your project. In that case you'd be looking for them to have written a ControllerFactory implementation.

If you can't figure it out from here, please add either the global.asax file, or the startup.cs file to your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM