Skip to content

Instantly share code, notes, and snippets.

@peaeater
Created May 8, 2020 22:05
Show Gist options
  • Select an option

  • Save peaeater/03af51663732d3075be9c481dae48c38 to your computer and use it in GitHub Desktop.

Select an option

Save peaeater/03af51663732d3075be9c481dae48c38 to your computer and use it in GitHub Desktop.

Revisions

  1. peaeater created this gist May 8, 2020.
    43 changes: 43 additions & 0 deletions Global.asax.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Andi.MVC.Core;
    using Andi.MVC.Core.Infrastructure.Globalization;

    namespace Andi.MVC.Web
    {
    public class MvcApplication : System.Web.HttpApplication
    {

    protected void Application_Start()
    {
    // MVC setup
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    MvcHandler.DisableMvcResponseHeader = true;
    // use globalized views if found
    /* N.B. Globalization is based on routes, culture is set in BaseController */
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new GlobalizedRazorViewEngine());

    // Resolve IOC dependencies
    IocContainer.Setup();

    // Web API config
    GlobalConfiguration.Configure(config =>
    {
    // set media route map
    config.Routes.MapHttpRoute(
    name: "Media",
    routeTemplate: "media/{*filepath}",
    defaults: new {controller = "MediaApi", filepath = RouteParameter.Optional});
    });
    }

    protected void Application_End()
    {
    IocContainer.Stop();
    }
    }
    }
    49 changes: 49 additions & 0 deletions IocContainer.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    using System.Threading;
    using System.Web.Http;
    using System.Web.Http.Dispatcher;
    using System.Web.Mvc;
    using Andi.MVC.Core.Infrastructure.DataAnnotations;
    using Andi.MVC.Core.Infrastructure.IOC;
    using Castle.Windsor;
    using Castle.Windsor.Installer;
    using FluentValidation.Mvc;

    namespace Andi.MVC.Core
    {
    public static class IocContainer
    {
    private static IWindsorContainer _container;

    public static void Setup()
    {
    _container = new WindsorContainer().Install(FromAssembly.This());

    // mvc controller factory
    var controllerFactory = new WindsorControllerFactory(_container.Kernel);
    ControllerBuilder.Current.SetControllerFactory(controllerFactory);

    // validator factory
    DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
    var validatorProvider = new FluentValidationModelValidatorProvider(new WindsorFluentValidatorFactory(_container.Kernel))
    {
    AddImplicitRequiredValidator = false
    };
    // force MVC to use fluent validation
    ModelValidatorProviders.Providers.Clear();
    ModelValidatorProviders.Providers.Add(validatorProvider);
    // force model metadata to use custom provider
    ModelMetadataProviders.Current = new CustomModelMetadataProvider(validatorProvider.ValidatorFactory);

    // resolve automapper maps
    AutoMapperBootstrapper.Configure(_container);

    //// web api controllers
    GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(_container.Kernel);
    }

    public static void Stop()
    {
    _container?.Dispose();
    }
    }
    }
    19 changes: 19 additions & 0 deletions MvcControllerInstaller.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    using System.Web.Mvc;
    using Castle.MicroKernel.Registration;
    using Castle.MicroKernel.SubSystems.Configuration;
    using Castle.Windsor;

    namespace Andi.MVC.Core.Infrastructure.IOC
    {
    public class MvcControllerInstaller : IWindsorInstaller
    {
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
    // Register controllers in the named assembly
    container.Register(
    Classes.FromAssemblyNamed("Andi.MVC.Web")
    .BasedOn<IController>()
    .ConfigureFor<IController>(x => x.LifestyleTransient()));
    }
    }
    }
    18 changes: 18 additions & 0 deletions WebApiControllerInstaller.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    using System.Web.Http;
    using Castle.MicroKernel.Registration;
    using Castle.MicroKernel.SubSystems.Configuration;
    using Castle.Windsor;

    namespace Andi.MVC.Core.Infrastructure.IOC
    {
    public class WebApiControllerInstaller : IWindsorInstaller
    {
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
    container.Register(
    Classes.FromAssemblyNamed("Andi.MVC.Web")
    .BasedOn<ApiController>()
    .ConfigureFor<ApiController>(x => x.LifestyleScoped()));
    }
    }
    }
    38 changes: 38 additions & 0 deletions WindsorDependencyResolver.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http.Dependencies;
    using Castle.MicroKernel;

    namespace Andi.MVC.Core.Infrastructure.IOC
    {
    internal class WindsorDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
    {
    private readonly IKernel _kernel;

    public WindsorDependencyResolver(IKernel kernel)
    {
    _kernel = kernel;
    }
    public IDependencyScope BeginScope()
    {
    return new WindsorDependencyScope(_kernel);
    }

    public void Dispose()
    {
    }

    public object GetService(Type serviceType)
    {
    return _kernel.HasComponent(serviceType) ? _kernel.Resolve(serviceType) : null;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
    return _kernel.ResolveAll(serviceType).Cast<object>();
    }


    }
    }
    36 changes: 36 additions & 0 deletions WindsorDependencyScope.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http.Dependencies;
    using Castle.MicroKernel;
    using Castle.MicroKernel.Lifestyle;

    namespace Andi.MVC.Core.Infrastructure.IOC
    {
    public class WindsorDependencyScope : IDependencyScope
    {
    private readonly IKernel _kernel;
    private readonly IDisposable _disposable;

    public WindsorDependencyScope(IKernel kernel)
    {
    _kernel = kernel;
    _disposable = kernel.BeginScope();
    }

    public void Dispose()
    {
    _disposable.Dispose();
    }

    public object GetService(Type serviceType)
    {
    return _kernel.HasComponent(serviceType) ? _kernel.Resolve(serviceType) : null;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
    return _kernel.ResolveAll(serviceType).Cast<object>();
    }
    }
    }