首页 > 解决方案 > 如何在 ASP.NET Core Web 应用程序中使用 Lamar 作为 NancyFx 中的 IOC?

问题描述

我正在构建一个 ASP.NET Core REST 服务。到目前为止,我有一个(工作的)ASP.NET Core (2.2) Web 应用程序,我已经将其更改为使用 Lamar IOC。它工作得很好。

我现在想将 Nancy(fx) 添加到此应用程序中,因为我真的想要我的 Nancy 路由。(我有点迷恋南希)。

如何将我的 ASP.NET IOC 容器连接到 Nancy,这样我就不会得到一个 Lamar 容器和一个 TinyIOC 容器。

我已经设法用结构图做到了这一点——非常成功,但这很容易——因为有一个 StructureMapNancyBootstrapper。我看过创建一个 LamarNancyBootstrapper - 但在 ASP.NET 环境中,这似乎很棘手/困难/奇怪?

有没有人做过这样的事情?

顺便提一句。我可以在 StartUp.Configure 方法中获取“原始” Lamar IContainer - 所以这不是问题。问题似乎与南希有关。

我设法做到了这一点,它似乎有效(有点)。不确定这是否朝着正确的方向发展。使用下面的代码 - NancySimpleViewEngine 尚未正确创建......所以,我仍然必须遗漏一些东西。

using System;
using System.Collections.Generic;
using System.Linq;
using global::Lamar;
using Nancy.Bootstrapper;
using Nancy.Diagnostics;
using Nancy.ViewEngines;
using Nancy.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Nancy.Bootstrappers.Lamar
{


    /// <summary>
    /// Nancy bootstrapper for the StructureMap container.
    /// </summary>
    public abstract class LamarNancyBootstrapper : NancyBootstrapperWithRequestContainerBase<IContainer>, IDisposable
    {
        private bool isDisposing = false;

        protected readonly IContainer _container;


        public LamarNancyBootstrapper(IContainer container)
        {
            _container = container;
        }
        /// <summary>
        /// Gets the diagnostics for initialisation
        /// </summary>
        /// <returns>An <see cref="IDiagnostics"/> implementation</returns>
        protected override IDiagnostics GetDiagnostics()
        {
            return this.ApplicationContainer.GetInstance<IDiagnostics>();
        }

        /// <summary>
        /// Gets all registered application startup tasks
        /// </summary>
        /// <returns>An <see cref="System.Collections.Generic.IEnumerable{T}"/> instance containing <see cref="IApplicationStartup"/> instances. </returns>
        protected override IEnumerable<IApplicationStartup> GetApplicationStartupTasks()
        {
            return this.ApplicationContainer.GetAllInstances<IApplicationStartup>();
        }

        /// <summary>
        /// Gets all registered request startup tasks
        /// </summary>
        /// <returns>An <see cref="IEnumerable{T}"/> instance containing <see cref="IRequestStartup"/> instances.</returns>
        protected override IEnumerable<IRequestStartup> RegisterAndGetRequestStartupTasks(IContainer container, Type[] requestStartupTypes)
        {
            return requestStartupTypes.Select(container.GetInstance).Cast<IRequestStartup>().ToArray();
        }

        /// <summary>
        /// Gets all registered application registration tasks
        /// </summary>
        /// <returns>An <see cref="System.Collections.Generic.IEnumerable{T}"/> instance containing <see cref="IRegistrations"/> instances.</returns>
        protected override IEnumerable<IRegistrations> GetRegistrationTasks()
        {
            return this.ApplicationContainer.GetAllInstances<IRegistrations>();
        }

        /// <summary>
        /// Resolve <see cref="INancyEngine"/>
        /// </summary>
        /// <returns><see cref="INancyEngine"/> implementation</returns>
        protected override INancyEngine GetEngineInternal()
        {
            return this.ApplicationContainer.GetInstance<INancyEngine>();
        }

        /// <summary>
        /// Gets the <see cref="INancyEnvironmentConfigurator"/> used by th.
        /// </summary>
        /// <returns>An <see cref="INancyEnvironmentConfigurator"/> instance.</returns>
        protected override INancyEnvironmentConfigurator GetEnvironmentConfigurator()
        {
            return this.ApplicationContainer.GetInstance<INancyEnvironmentConfigurator>();
        }

        /// <summary>
        /// Get the <see cref="INancyEnvironment" /> instance.
        /// </summary>
        /// <returns>An configured <see cref="INancyEnvironment" /> instance.</returns>
        /// <remarks>The boostrapper must be initialised (<see cref="INancyBootstrapper.Initialise" />) prior to calling this.</remarks>
        public override INancyEnvironment GetEnvironment()
        {
            return this.ApplicationContainer.GetInstance<INancyEnvironment>();
        }

        /// <summary>
        /// Registers an <see cref="INancyEnvironment"/> instance in the container.
        /// </summary>
        /// <param name="container">The container to register into.</param>
        /// <param name="environment">The <see cref="INancyEnvironment"/> instance to register.</param>
        protected override void RegisterNancyEnvironment(IContainer container, INancyEnvironment environment)
        {
            container.Configure(registry => registry.Add( new ServiceDescriptor(typeof(INancyEnvironment), environment)));
        }

        /// <summary>
        /// Gets the application level container
        /// </summary>
        /// <returns>Container instance</returns>
        protected override IContainer GetApplicationContainer()
        {
            return _container;
        }

        /// <summary>
        /// Register the bootstrapper's implemented types into the container.
        /// This is necessary so a user can pass in a populated container but not have
        /// to take the responsibility of registering things like <see cref="INancyModuleCatalog"/> manually.
        /// </summary>
        /// <param name="applicationContainer">Application container to register into</param>
        protected override void RegisterBootstrapperTypes(IContainer applicationContainer)
        {
            applicationContainer.Configure(registry =>
            {
                registry.Add(new ServiceDescriptor(typeof(INancyModuleCatalog), this));
                registry.Add(new ServiceDescriptor(typeof(IFileSystemReader),  new DefaultFileSystemReader()));
            });
        }

        /// <summary>
        /// Register the default implementations of internally used types into the container as singletons
        /// </summary>
        /// <param name="container">Container to register into</param>
        /// <param name="typeRegistrations">Type registrations to register</param>
        protected override void RegisterTypes(IContainer container, IEnumerable<TypeRegistration> typeRegistrations)
        {
            container.Configure(registry =>
            {
                foreach (var typeRegistration in typeRegistrations)
                {
                    ServiceLifetime lifeTime = ServiceLifetime.Transient;
                    if (typeRegistration.Lifetime == Lifetime.Singleton) lifeTime = ServiceLifetime.Singleton;
                    else if (typeRegistration.Lifetime == Lifetime.PerRequest) lifeTime = ServiceLifetime.Scoped;

                    registry.Add(new ServiceDescriptor(typeRegistration.RegistrationType, typeRegistration.ImplementationType, lifeTime));

                }
            });
        }

        /// <summary>
        /// Register the various collections into the container as singletons to later be resolved
        /// by IEnumerable{Type} constructor dependencies.
        /// </summary>
        /// <param name="container">Container to register into</param>
        /// <param name="collectionTypeRegistrationsn">Collection type registrations to register</param>
        protected override void RegisterCollectionTypes(IContainer container, IEnumerable<CollectionTypeRegistration> collectionTypeRegistrationsn)
        {
            container.Configure(registry =>
            {
                foreach (var collectionTypeRegistration in collectionTypeRegistrationsn)
                {
                    foreach (var implementationType in collectionTypeRegistration.ImplementationTypes)
                    {
                        registry.Add(new ServiceDescriptor(collectionTypeRegistration.RegistrationType, implementationType, ServiceLifetime.Transient));
                   }
                }
            });
        }

        /// <summary>
        /// Register the given instances into the container
        /// </summary>
        /// <param name="container">Container to register into</param>
        /// <param name="instanceRegistrations">Instance registration types</param>
        protected override void RegisterInstances(IContainer container, IEnumerable<InstanceRegistration> instanceRegistrations)
        {
            container.Configure(registry =>
            {
                foreach (var instanceRegistration in instanceRegistrations)
                {
                    registry.Add(new ServiceDescriptor(instanceRegistration.RegistrationType, instanceRegistration.Implementation));
                }
            });
        }



        /// <summary>
        /// Register the given module types into the request container
        /// </summary>
        /// <param name="container">Container to register into</param>
        /// <param name="moduleRegistrationTypes"><see cref="INancyModule"/> types</param>
        protected override void RegisterRequestContainerModules(IContainer container, IEnumerable<ModuleRegistration> moduleRegistrationTypes)
        {

            container.Configure(registry =>
            {
                foreach (var registrationType in moduleRegistrationTypes)
                {
                    registry.Add(new ServiceDescriptor(typeof(INancyModule), registrationType.ModuleType, ServiceLifetime.Transient));     
                }
            });
        }

        /// <summary>
        /// Retrieve all module instances from the container
        /// </summary>
        /// <param name="container">Container to use</param>
        /// <returns>Collection of <see cref="INancyModule"/> instances</returns>
        protected override IEnumerable<INancyModule> GetAllModules(IContainer container)
        {
            return container.GetAllInstances<INancyModule>();
        }

        /// <summary>
        /// Retreive a specific module instance from the container
        /// </summary>
        /// <param name="container">Container to use</param>
        /// <param name="moduleType">Type of the module</param>
        /// <returns>A <see cref="INancyModule"/> instance</returns>
        protected override INancyModule GetModule(IContainer container, Type moduleType)
        {
            return (INancyModule)container.GetInstance(moduleType);
        }

        public new void Dispose()
        {
            if (this.isDisposing)
            {
                return;
            }

            this.isDisposing = true;
            base.Dispose();
        }


    }
}

标签: structuremapasp.net-core-2.1nancylamar

解决方案


推荐阅读