Как настроить контроллер, чтобы конструктор вызывался с аргументом хранилища - PullRequest
0 голосов
/ 11 марта 2019

Имея испорченные книги, я не могу понять, что в проекте C # MVC, который я принимаю, заставляет конструкторы Controller всегда передавать аргумент хранилища.

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

Даже другие классы, которыеНЕ партиалы написаны таким образом.Я посмотрел на класс (или интерфейс), от которого они наследуются.Есть идеи?Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 11 марта 2019

Это называется внедрением зависимости.

Ядро 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>();
}
1 голос
/ 11 марта 2019

Как уже говорили другие, внедрение зависимости. Но некоторые подробности:

.net Framework и ядро ​​.net обрабатывают его по-разному.

Он вообще не встроен в .net framework. Вы захотите проверить свой файл global.asax, чтобы выяснить, что происходит. Большую часть времени это делается через пакет nuget. Есть много популярных, таких как autofaq, ninject, simple инжектор и т. д. Вы должны увидеть некоторые вещи о создании контейнера и регистрации сервисов.

.net ядро ​​имеет собственную инфраструктуру внедрения зависимостей, с которой оно поставляется, поэтому довольно часто оно используется. Хотя иногда люди все еще используют пакет nuget для чего-то более сложного. Материал ядра .net будет находиться в файле Startup.cs. Посмотрите, есть ли что-нибудь, похожее на сервисы.

Возможно, хотя вряд ли кто-то написал в вашем проекте собственную структуру внедрения зависимостей. В этом случае вам нужно, чтобы они написали реализацию ControllerFactory.

Если вы не можете понять это отсюда, пожалуйста, добавьте либо файл global.asax, либо файл startup.cs к вашему вопросу.

1 голос
/ 11 марта 2019

Это Внедрение зависимостей , посмотрите при запуске что-то вроде

services.AddTransiant<IDataRepository, DataRepo>();

Это указывает контейнеру внедрения зависимостей создавать экземпляр IDataRepository с экземпляром DataRepo.

...