IControllerFactory

IControllerFactory 는 컨트롤러 객체를 반환하거나 객체 릴리즈 시키는 팩토리 인터페이스이다. ASP.NET MVC 4 까지 지원하지 않았던 DI(Dependency Injection) 기능을 사용하기 위해 이 인터페이스를 구현하여 사용하였다.

ASP.NET Core 에서는 객체 주입(Injection) 할 때 한 가지 큰 단점이 있다.

생성자 주입(Constructor Injection) 으로만 DI(Dependency Injection) 기능을 사용할 수 있다. 이 방법은 필자가 가장 좋아하지 않는 방법인데, 그 사용성이 여간 귀찮을 수 없다.

이 아티클에서는 프로퍼티 인젝션(Property Injection) 이 가능한 Unity Application Block 을 사용하기 위해 IControllerFactory 를 마이그레이션 하는 것을 목표로 한다.

- 레거시 ASP.NET MVC 에서 IControllerFactory 설정

Controller 클래스들을 IoC(Inversion of Control) 컨테이너(Container) 에 담아 놓고, 꺼내쓸 때 DI(Dependency Injection) 을 시키는 방식이다. 이렇게 하면 사용하는 입장에서는 복잡한 객체와 인스턴스 관계를 파악할 필요 없이 꺼내 쓰면 되는 것이다. 당연 단위 테스트에서도 간결하게 사용할 수 있게 된다.

global.asax.cs

ControllerBuilder 클래스를 이용하여 IControllerFactory 인스턴스를 설정한다.

// 종속성 주입 설정
Application.Lock();
{
    Container = configureContainer();
    ControllerBuilder.Current.SetControllerFactory(new FrameworkControllerFactory(Container));
}
Application.UnLock();

FrameworkControllerFactory.cs

public class FrameworkControllerFactory : DefaultControllerFactory
{
    private readonly IFrameworkContainer container;

    public FrameworkControllerFactory(IFrameworkContainer container)
    {
        this.container = container;
    }

    #region Overrides of DefaultControllerFactory

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            requestContext.HttpContext.Response.Redirect("/", true);
        }

        var controller = container.Resolve(controllerType);
        return controller as IController;
    }

    #endregion
}

- ASP.NET Core 에서 IControllerFactory 설정

ASP.NET Core 에서는 상당수 서비스 클래스와 인스턴스들이 IoC Container 에 등록되어 여기에서 객체를 불러 사용하고 있는 형태다. IServiceCollection 인터페이스에 서비스에 ASP.NET Core 가 동작하기 위한 코어 클래스들이 등록되어 있다.

IServiceCollection 에 Singleton 객체로 services.AddSingleton<IControllerFactory, FrameworkControllerFactory>(); 하게되면 IControllerFactory 가 등록된다.

그럼 IServiceCollection 에는 IControllerFactory 가 두 개 등록이 되어있는데, 나머지 하나가 DefaultControllerFactory 클래스이다. 이 때, ASP.NET Core는 가장 마지막에 등록된 IControllerFactory 클래스를 반환한다.

먼저, Nuget 을 통해 Unity Application Block 을 설치한다.

Startup.cs

public class Startup
{
    public static IUnityContainer Container = new UnityContainer();

    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        services.AddMvc();

        // IControllerFactory 설정
        services.AddSingleton<IControllerFactory, FrameworkControllerFactory>();
    }
}

FrameworkControllerFactory.cs

public class FrameworkControllerFactory : IControllerFactory
{
    public object CreateController(ControllerContext context)
    {
        return Startup.Container.Resolve(context.ActionDescriptor.ControllerTypeInfo.AsType());
    }

    public void ReleaseController(ControllerContext context, object controller)
    {
    }
}

모든 설정이 다 되었으면, Unity Container 에서 DI(Dependency Injection) 을 수행하는 HomeController 가 정상적으로 동작하게 된다.

HomeController.cs

public class HomeController : Controller
{
    [Dependency]
    public MessageService MessageService { get; set; }

    public IActionResult Index()
    {
        MessageService.Say();

        return View();
    }
}

public class MessageService
{
    public void Say()
    {
        Console.WriteLine("MessageService Resolved. ===========================");
    }
}


저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by 땡초 POWERUMC

댓글을 달아 주세요