如何在ASP.NET Core Web应用程序内的NancyFx中将Lamar用作IOC?

时间:2019-04-10 13:45:26

标签: structuremap asp.net-core-2.1 nancy lamar

我正在构建一个ASP.NET Core REST服务。到目前为止,我有一个(正在运行的)ASP.NET Core(2.2)Web应用程序,我已对其进行了更改以使用Lamar IOC。它工作得很漂亮。

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

如何将ASP.NET IOC容器连接到Nancy,以免最终没有Lamar容器和TinyIOC容器。

我已经成功地使用structuremap做到了这一点-相当成功,但这很容易-因为有一个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();
        }


    }
}

0 个答案:

没有答案