diff --git a/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/ControllerFactory.cs b/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/ControllerFactory.cs index 0ff70df4..5a7aa051 100644 --- a/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/ControllerFactory.cs +++ b/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/ControllerFactory.cs @@ -1,6 +1,55 @@ namespace LaaProductionWeb.App_Infrastructure { - public class ControllerFactory + using System; + using System.Web; + using System.Web.Mvc; + using System.Web.Routing; + using System.Web.SessionState; + + public class ControllerFactory : IControllerFactory { + const string AREAS_PATTERN = "LaaProductionWeb.Areas.{0}.Controllers.{1}Controller"; + const string CONTROLLERS_PATTERN = "LaaProductionWeb.Controllers.{0}Controller"; + + private readonly IServiceProvider serviceProvider; + + public ControllerFactory(IServiceProvider serviceProvider) + => this.serviceProvider = serviceProvider; + + public IController CreateController(RequestContext requestContext, string controllerName) + { + var controllerTypeName = requestContext.RouteData.DataTokens.TryGetValue("area", out object areaName) + ? string.Format(AREAS_PATTERN, areaName, controllerName) + : string.Format(CONTROLLERS_PATTERN, controllerName); + var controllerType = Type.GetType(controllerTypeName, throwOnError: false, ignoreCase: true); + + this.RedirectToDefaultIfNotFound(controllerType, requestContext.HttpContext.Response); + + var controller = this.serviceProvider.GetService(controllerType) as IController; + + this.RedirectToDefaultIfNotFound(controller, requestContext.HttpContext.Response); + + return controller; + } + + public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) + => SessionStateBehavior.Default; + + public void ReleaseController(IController controller) + { + if (controller is IDisposable disposable) + { + disposable.Dispose(); + } + } + + private void RedirectToDefaultIfNotFound(object resource, HttpResponseBase response) + { + if (response is null) + { + response.RedirectToRoute("MVC_Default"); + response.End(); + } + } } } \ No newline at end of file diff --git a/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/Interfaces/ITransient.cs b/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/Interfaces/ITransient.cs new file mode 100644 index 00000000..f75e3a4b --- /dev/null +++ b/LaaProductionWeb/LaaProductionWeb/App_Infrastructure/Interfaces/ITransient.cs @@ -0,0 +1,6 @@ +namespace LaaProductionWeb.App_Infrastructure.Interfaces +{ + public interface ITransient + { + } +} diff --git a/LaaProductionWeb/LaaProductionWeb/App_Start/RouteConfig.cs b/LaaProductionWeb/LaaProductionWeb/App_Start/RouteConfig.cs index 1e7010a5..10290c8e 100644 --- a/LaaProductionWeb/LaaProductionWeb/App_Start/RouteConfig.cs +++ b/LaaProductionWeb/LaaProductionWeb/App_Start/RouteConfig.cs @@ -10,7 +10,7 @@ routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( - name: "Default", + name: "MVC_Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }); } diff --git a/LaaProductionWeb/LaaProductionWeb/App_Start/ServicesConfig.cs b/LaaProductionWeb/LaaProductionWeb/App_Start/ServicesConfig.cs index eebe9eb3..07bcc1ba 100644 --- a/LaaProductionWeb/LaaProductionWeb/App_Start/ServicesConfig.cs +++ b/LaaProductionWeb/LaaProductionWeb/App_Start/ServicesConfig.cs @@ -1,10 +1,80 @@ namespace LaaProductionWeb.App_Start { - public class ServicesConfig + using LaaProductionWeb.App_Infrastructure; + using LaaProductionWeb.App_Infrastructure.Interfaces; + + using Microsoft.Extensions.DependencyInjection; + + using System; + using System.Collections.Generic; + using System.Linq; + using System.Web.Mvc; + + public static class ServicesConfig { public static void RegisterServices() - { + => new ServiceCollection() + .ConfigureServices() + .BuildServiceProvider() + .BuildControllerFactory(); + static IServiceCollection ConfigureServices(this IServiceCollection services) + { + var assembly = typeof(ServicesConfig).Assembly; + var types = assembly.GetTypes(); + + services + .AddControllers(types) + .AddTransients(types); + + return services; + } + + static IServiceCollection AddControllers(this IServiceCollection services, IEnumerable assemblyTypes) + { + var controllers = assemblyTypes.Where(x => !x.IsAbstract && typeof(IController).IsAssignableFrom(x)); + + foreach (var controller in controllers) + { + services.AddTransient(controller); + } + + return services; + } + + static IServiceCollection AddTransients(this IServiceCollection services, IEnumerable assemblyTypes) + { + var assemblyServices = assemblyTypes.Where(x => !x.IsAbstract && typeof(TInterface).IsAssignableFrom(x)); + + foreach (var service in assemblyServices) + { + var interfaces = service + .GetInterfaces() + .Where(x => x != typeof(TInterface)); + + if (!interfaces.Any()) + { + services.AddTransient(service); + } + else + { + foreach (var @interface in interfaces) + { + services.AddTransient(@interface, service); + } + } + } + + return services; + } + + static IServiceProvider BuildControllerFactory(this IServiceProvider serviceProvider) + { + var controllerFactory = new ControllerFactory(serviceProvider); + + ControllerBuilder.Current.SetControllerFactory(controllerFactory); + + return serviceProvider; } } } \ No newline at end of file diff --git a/LaaProductionWeb/LaaProductionWeb/Global.asax.cs b/LaaProductionWeb/LaaProductionWeb/Global.asax.cs index 4ea59188..6366e299 100644 --- a/LaaProductionWeb/LaaProductionWeb/Global.asax.cs +++ b/LaaProductionWeb/LaaProductionWeb/Global.asax.cs @@ -1,5 +1,7 @@ namespace LaaProductionWeb { + using LaaProductionWeb.App_Start; + using System.Web; using System.Web.Http; using System.Web.Mvc; @@ -10,6 +12,7 @@ { protected void Application_Start() { + ServicesConfig.RegisterServices(); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); diff --git a/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj b/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj index 7cbb485f..2505220c 100644 --- a/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj +++ b/LaaProductionWeb/LaaProductionWeb/LaaProductionWeb.csproj @@ -137,6 +137,7 @@ +