0

私は LightInject をいじって、ドメイン プロジェクト、インフラストラクチャ プロジェクト、MVC プロジェクト、および DependencyResolution プロジェクトを含む IoC ソリューションをセットアップしようとしています。インフラストラクチャ、MVC、および DependencyResolution はドメインを参照します。MVC は DependencyResolution を参照し、DependencyResolution は LightInject を参照します。

DependencyResolution は、アプリの起動時に必要なすべての依存関係を登録するという考え方です。現時点では、MVC プロジェクト内のコントローラーは認識されていません。代わりに、未知の MVC コントローラー クラスをすべてキャッチするフォールバック ルーチンをセットアップしました。フォールバック ルーチンでは、MVC コントローラーを登録して返します。これを行うことで、MVC コントローラーがまだ登録されていない最初のヒットによってのみ実行されるため、このコードは 1 回だけ実行されることが期待されます。しかし、そうではありません。代わりに、最初に登録されたにもかかわらず、MVC コントローラーが要求されるたびにフォールバック ルーチンがヒットするため、StackOverflowException が発生します。

では、問題は、なぜこれが起こるのかということです。これは予想される動作ですか? もしそうなら、なぜですか? また、それを回避する方法はありますか?

編集:これが以下のソースコードです。

[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

このメソッドは、2 番目のパラメーターとしてファクトリ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 に答える