Dependency Injection configuration, Controller Factory

This commit is contained in:
Stoyan Zlatev
2023-04-03 12:43:10 +02:00
parent df2b50300f
commit 45808120d9
6 changed files with 133 additions and 4 deletions
@@ -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();
}
}
}
}
@@ -0,0 +1,6 @@
namespace LaaProductionWeb.App_Infrastructure.Interfaces
{
public interface ITransient
{
}
}
@@ -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 });
}
@@ -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<ITransient>(types);
return services;
}
static IServiceCollection AddControllers(this IServiceCollection services, IEnumerable<Type> 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<TInterface>(this IServiceCollection services, IEnumerable<Type> 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;
}
}
}
@@ -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);
@@ -137,6 +137,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="App_Infrastructure\ControllerFactory.cs" />
<Compile Include="App_Infrastructure\Interfaces\ITransient.cs" />
<Compile Include="App_Start\BundleConfig.cs" />
<Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="App_Start\RouteConfig.cs" />