Настройки Unity 2.0 Web.config с MVC - PullRequest
3 голосов
/ 13 октября 2010

Я пытаюсь использовать Unity 2.0 для моего текущего проекта с MVC, и у меня возникают проблемы с настройкой внедрения параметров в файле web.config.

Вот что у меня есть:

1) Домашний контроллер:

public class HomeController : Controller
{
    IRepository repository = null;

    public HomeController()
    {
       // Always calls this constructor. Why? 
       // Should be calling the constructor below that takes IRepository.
    }

    public HomeController(IRepository repository)
    {
        // Should be calling this constructor!!!
        this.repository = repository;
    }
    public ActionResult Index()
    {
        List<int> intList = this.repository.GetInts();

        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

Базовый контроллер с двумя конструкторами. 1-й из них не принимает аргументов, а 2-й принимает IRepository в качестве аргумента (который должен быть введен Unity)

2) Репозиторий SQL

public class SQLRepository : IRepository
{
    private string connectionString = null;

    public SQLRepository(string connectionString)
    {
        this.connectionString = connectionString;
    }

    #region IRepository Members

    public List<int> GetInts()
    {
        return new List<int>() { 1, 2, 3, 4, 5 };
    }

    #endregion
}

Будущее за SQL-репозиторием, но сейчас он просто реализует 1 элемент интерфейса IRepository, а именно GetInts (), и возвращает список целых чисел.

3) IRepository Interace

public interface IRepository
{
    List<int> GetInts();
}

Интерфейс.

4) Событие Application_Start () в моем файле Global.asax.

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterRoutes(RouteTable.Routes);

        IUnityContainer container = new UnityContainer();

        UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
        section.Configure(container, "Default");
    }

Используется для чтения конфигурации Unity 2.0 из файла web.config для регистрации и отображения типов и т. Д.

6) Раздел конфигурации Unity 2.0 в web.config

<unity>
<typeAliases>
  <typeAlias alias="string" type="System.String, mscorlib" />
  <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
  <typeAlias alias="IRepository" type="NewMVCApp.Interfaces.IRepository, NewMVCApp" />
  <typeAlias alias="SQLRepository" type="NewMVCApp.Repository.SQLRepository, NewMVCApp" />
</typeAliases>
<containers>
  <container name="Default">
    <types>
      <type type="IRepository" mapTo="SQLRepository">
        <lifetime type="singleton" />
        <constructor>
          <param name="connectionString">
            <value value="ApplicationServices" />
          </param>
        </constructor>
      </type>
    </types>
  </container>
</containers>

Это раздел конфигурации Unity 2.0, который я использую. Как вы можете видеть, введите typeAlias ​​как для моего IRepository, так и для моих классов SQLRepository, а затем сопоставьте IRepository с SQLRepository. Чтобы в любое время запрашивать IRepository, будет предоставлен экземпляр SQLRepository. Кроме того, я хочу передать строку подключения через конструктор в мой SQLRepository.

5) Итак, что я пытаюсь сделать?

Я пытаюсь использовать Unity 2.0 для передачи экземпляра IRepository (SQLRepository) в мой HomeController. Но по какой-то причине вызывается конструктор по умолчанию, без параметров, для HomeController (). Но HomeController (репозиторий IRepository) никогда не вызывается. Я вполне уверен, что я не настроил все правильно в файле web.config. Но я не уверен, как правильно все настроить, чтобы вызывался правильный конструктор на HomeController. Пожалуйста, помогите:)

& Спасибо:)

Ответы [ 3 ]

6 голосов
/ 13 октября 2010

Ваша конфигурация Unity выглядит нормально.Проблема в том, что вы не подключили Unity к инфраструктуре MVC, поэтому платформа не использует контейнер для создания вашего контроллера, вместо этого MVC использует логику по умолчанию, которая вызывает конструктор по умолчанию.

Вам нужны две вещи.Во-первых, реализация IControllerFactory.Я обычно использую это:

public class UnityControllerFactory : DefaultControllerFactory
{
    private readonly IUnityContainer container;

    public UnityControllerFactory(IUnityContainer container)
    {
        this.container = container;
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if(controllerType != null)
            return container.Resolve(controllerType) as IController;
        return base.GetControllerInstance(requestContext, controllerType);
    }
}

Во-вторых, вам нужно указать инфраструктуре MVC использовать эту фабрику контроллеров вместо стандартной.Вы делаете это в вашем обработчике Application_Start.Сделайте это:

ControllerBuilder.Current.SetControllerFactory(
    new UnityControllerFactory(container));

Как только вы это сделаете, ваши контроллеры будут созданы через контейнер, и все должно начать работать.

1 голос
/ 13 октября 2010

Большое спасибо, Крис !! Вот и все! Вот как должно выглядеть событие Application_Start () в MVC2 с использованием Unity 2.0:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterRoutes(RouteTable.Routes);

        IUnityContainer container = new UnityContainer();

        IControllerFactory controllerFactory = new UnityControllerFactory(container);
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);

        // Do the line below only if you want to Register IoC programatically
        //container.RegisterType<IRepository, SQLRepository>(new ContainerControlledLifetimeManager());

        UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
        section.Configure(container, "Default");
    }
0 голосов
/ 22 апреля 2015

Попробуйте с пакетами Unity.Mvc nuget. Вы можете использовать container.LoadConfiguration(); в UnityConfig классе.

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        container.LoadConfiguration();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}

Затем вы можете обновить web.config, как показано ниже.

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity configSource="unity.config" />

Полный текст статьи можно найти @ MVC 5 с Unity для внедрения зависимостей .

...