0

我正在摆弄 LightInject 来尝试设置一个 IoC 解决方案,其中包含一个域项目、一个基础设施项目、一个 MVC 项目和一个 DependencyResolution 项目。Infrastructure、MVC 和 DependencyResolution 引用域。MVC 引用 DependencyResolution 和 DependencyResolution 引用 LightInject。

这个想法是 DependencyResolution 在应用程序启动时注册所有必要的依赖项。目前它不了解 MVC 项目中的控制器。相反,我设置了一个备用例程来捕获所有未知的 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);
        }
    }
}
4

1 回答 1

1

RegisterFallback方法需要一个工厂作为第二个参数,并且似乎没有以容器可以解析它的方式注册类型。

您的工厂需要新建实例并将其传回。

Func<ServiceRequest, object> fallback = request =>
{
    if (request.ServiceType == typeof(XYZController))
    {
        return new XYZController(container.GetInstance<IDependency>());
    }
    else
    {
        throw new InvalidOperationException(request.ServiceType.FullName);
    }
};

这可能是一个值得向开发人员提出的问题。


您可以使用如下代码加载 MVC 程序集:

private IEnumerable<Assembly> LoadAssemblies(string folder)
{
    var dlls =
        from file in new DirectoryInfo(folder).GetFiles()
        where file.Extension == ".dll"
        select file.FullName;

    var assemblies = new List<Assembly>();

    foreach (string dll in dlls) {
        try {
            assemblies.Add(Assembly.LoadFile(dll));
        }
        catch { }
    }

    return assemblies;
}

并使用 LightInject MVC 集成包注册所有控制器

于 2015-04-30T09:52:40.023 回答