Как вы используете Lamar в качестве IOC в NancyFx внутри веб-приложения ASP.NET Core? - PullRequest
1 голос
/ 10 апреля 2019

Я создаю ASP.NET Core REST Service.До сих пор у меня есть (работающее) веб-приложение ASP.NET Core (2.2), которое я изменил, чтобы использовать Lamar IOC.Работает красиво.

Теперь я хочу добавить Нэнси (fx) в это приложение, потому что я ДЕЙСТВИТЕЛЬНО хочу свою Nancy-маршрутизацию.(Я немного влюблен в Нэнси).

Как мне подключить мой контейнер ASP.NET IOC к Нэнси, чтобы у меня не было контейнера Lamar и контейнера TinyIOC.

Мне удалось сделать это с Structuremap - довольно успешно, но это было легко - так как есть StructureMapNancyBootstrapper.Я смотрел на создание LamarNancyBootstrapper - но в среде ASP.NET это кажется сложным / сложным / странным?

Кто-нибудь делал что-нибудь подобное?

Кстати.Я могу заполучить «сырого» Ламара IContainer в методе StartUp.Configure, так что это не проблема.Кажется, проблема только в том, чтобы связать это с Нэнси.

Мне удалось зайти так далеко, и, похоже, это работает (вроде).Не уверен, что это движется в правильном направлении.С приведенным ниже кодом - 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();
        }


    }
}
...