Если вы используете MVC 3, чтобы сделать все правильно, вы должны использовать встроенные биты разрешения зависимостей. Я настоятельно рекомендую вам прочитать серию сообщений в блоге Брэда Уилсона (члена команды ASP.NET MVC).
Что касается конкретной реализации StructureMap, я нашел полезными следующие посты в блоге.
StructureMap и ASP.NET MVC 3 - Начало работы
StructureMap, привязки модели и внедрение зависимостей в ASP.NET MVC 3
StructureMap, фильтры действий и внедрение зависимостей в ASP.NET MVC 3
StructureMap, фильтры глобальных действий и внедрение зависимостей в ASP.NET MVC 3
В любом случае, вот код. Для начала я бы предложил установить пакет NuGet StructureMap-MVC3 .
Я не могу вспомнить, что именно он создает в файлах, но вот что в основном связано.
/ App_Start / StructuremapMvc.cs - это подключается к Application_Start и устанавливает ваш контейнер (SmIoC.Initialize()
), а затем устанавливает MVC 3 DependencyResolver в ваш SmDependencyResolver
using System.Web.Mvc;
using YourAppNamespace.Website.IoC;
using StructureMap;
[assembly: WebActivator.PreApplicationStartMethod(typeof(YourAppNamespace.App_Start.StructuremapMvc), "Start")]
namespace YourAppNamespace.Website.App_Start {
public static class StructuremapMvc {
public static void Start() {
var container = SmIoC.Initialize();
DependencyResolver.SetResolver(new SmDependencyResolver(container));
}
}
}
/ IoC / SmDependencyResolver.cs - это ваша реализация MVC 3 IDependencyResolver. Он используется в приведенном выше коде App_Start.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StructureMap;
namespace YourAppNamespace.Website.IoC
{
public class SmDependencyResolver : IDependencyResolver
{
private readonly IContainer _container;
public SmDependencyResolver(IContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
if (serviceType == null)
{
return null;
}
try
{
return _container.GetInstance(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>(); ;
}
}
}
/ IoC / SmIoC.cs - здесь вы настраиваете свой контейнер ... также используется в коде App_Start.
namespace YourAppNamespace.Website.IoC
{
public static class SmIoC
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
//etc...
});
return ObjectFactory.Container;
}
}
}
Теперь все подключено ... (я думаю ;-), но у вас еще есть кое-что сделать. Внутри вашего Global.asax
мы должны убедиться, что вы утилизируете все, что относится к области действия HttpContext.
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
Таким образом, вы должны быть в состоянии добиться внедрения зависимости через внедрение конструктора, что является правильным способом выполнения каких-либо действий.