Занимавам се с LightInject, за да опитам да настроя IoC решение, съдържащо Domain proj, Infrastructure proj, MVC proj и DependencyResolution proj. Инфраструктура, MVC и DependencyResolution препратки към домейн. MVC препраща към DependencyResolution и DependencyResolution препраща към LightInject.
Идеята е, че DependencyResolution регистрира всички необходими зависимости при стартиране на приложението. Понастоящем няма познания за контролерите в MVC proj. Вместо това създадох резервна рутина за улавяне на всички неизвестни класове на MVC контролер. След това в резервната рутина регистрирам MVC контролера и го връщам. Като правя това, очаквам този код да се изпълнява само веднъж, тъй като само при първото попадение MVC контролерът все още не е регистриран. Но това не е така. Вместо това получавам StackOverflowException, защото резервната рутина е ударена всеки път, когато се поиска MVC контролерът, въпреки че е регистриран за първи път.
Така че въпросът е защо това се случва? Това очаквано поведение ли е и ако е така, защо е така и как да го заобиколите?
Редактиране: Ето изходния код по-долу.
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(DependencyResolution.App_Start.WebCommon), "Start")]
namespace DependencyResolution.App_Start
{
static class WebCommon
{
private static readonly TempProject.LightInject.ServiceContainer _serviceContainer = new TempProject.LightInject.ServiceContainer();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
var container = _serviceContainer;
RegisterServices(container);
Domain.ServiceLocator.SetServiceLocator(() => new ServiceLocator(container));
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="container">The IoC container.</param>
private static void RegisterServices(TempProject.LightInject.ServiceContainer container)
{
System.Func<TempProject.LightInject.ServiceRequest, object> fallback = request =>
{
var serviceType = request.ServiceType;
container.Register(serviceType, serviceType);
return container.GetInstance(serviceType);
};
container.RegisterFallback((type, s) => type.Name.EndsWith("Controller"), request => fallback(request));
var assembly = typeof(Domain.IServiceLocator).Assembly;
container.RegisterAssembly(assembly);
}
}
}