normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

ASP.NET MVC with Quill

色々とカスタマイズが可能になっているASP.NET MVCであり、ASP.NET MVCDIコンテナ系との親和性はかなり高いと思います。しかし、なぜかNInjectでの記事は載っているのに、日本語の記事でエントリーに上がっていません。なので、記事がなかったので書いてみました。手順としては、おおよそ以下の感じになります。

  1. 参照の追加
  2. DefaultControllerFactory の継承クラス作成
  3. Global.asax への追記
  4. インタフェース、実装クラスの作成
  5. Controller作成

参照の追加。

以下のDLLに対し、参照を追加します。

DefaultControllerFactory の継承クラス作成

とりあえずごにょっと実装。

    public class QuillControllerFactory : DefaultControllerFactory
    {
        QuillInjector injector = QuillInjector.GetInstance();

        override public IController CreateController(RequestContext requestContext, string controllerName)
        {
            Trace.WriteLine("RequestContext = " + requestContext.ToString() + ", controller = " + controllerName);
            IController controller = base.CreateController(requestContext, controllerName);
            injector.Inject(controller);
            return controller;
        }

        protected override IController GetControllerInstance(Type controllerType)
        {
            IController controller =  base.GetControllerInstance(controllerType);
            injector.Inject(controller);
            return controller;
        }

        public override void ReleaseController(IController controller)
        {
            Trace.WriteLine("IController = " + controller.ToString());
            base.ReleaseController(controller);
        }
    }

Global.asax への追記

ASP.NET MVCが内部で持っているControllerFactoryのクラスを入れ替えます。これで作成したQuillControllerFactoryがASP.NET MVCの内部でも動作します。

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
            
            // Controllerの作成クラスを入れ替える
            ControllerBuilder.Current.SetControllerFactory(new QuillControllerFactory());
        }

インタフェース、実装クラスの作成

なんの面白みもなく以下を作成。

    public class StudentDto
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public long Age { get; set; }
        public string Comment { get; set; }
    }


    [Implementation(typeof(StudentRepository))]
    public interface IRepository<T>
    {
        T Get(long id);
        IQueryable<T> GetAll();
        void Add(T obj);
        void Remove(T obj);
    }

    public class StudentRepository : IRepository<StudentDto>
    {
        public StudentDto Get(long id)
        {
            Trace.WriteLine( "@@" + this.GetType().FullName + "#"+  MethodInfo.GetCurrentMethod().Name );
            return null;
        }

        public IQueryable<StudentDto> GetAll()
        {
            Trace.WriteLine("@@" + this.GetType().FullName + "#" + MethodInfo.GetCurrentMethod().Name);
            return null;
        }

        public void Add(StudentDto obj)
        {
            Trace.WriteLine("@@" + this.GetType().FullName + "#" + MethodInfo.GetCurrentMethod().Name);
        }

        public void Remove(StudentDto obj)
        {
            Trace.WriteLine("@@" + this.GetType().FullName + "#" + MethodInfo.GetCurrentMethod().Name);
        }
    }

Controller作成

最後にコントローラを作成。これは単にインタフェースを定義しておくだけです。

    public class HomeController : MyController
    {
        private IRepository<StudentDto> studentRepository;
        public ActionResult Index(string comment)
        {
            if (string.IsNullOrEmpty(comment) == false)
            {
                ViewData["Message"] = "送信したコメント : " + comment;
            }

            studentRepository.GetAll();

            return View();
        }

とりあえず、この動作でコメントが出るかチェックしたところ、元気に動作しておりました。