Alexander Beletsky's development blog

My profession is engineering

Latest version of ELMAH MVC controller

Integrating ELMAH to ASP.NET MVC in right way is blog post I created sometime ago. It appears really popular, because a lot of people had the same issue as me and found solution I created really applicable. It was really cool to receive all that feedback! By the way, elmah.mvc.controller is my first github repository I got pull request!

Especially, I would like to thank to Seba Illingworth and Barry Dorrans who found really nasty issues and helped to fix those.

The controller’s code has been moved to github long time ago, but what I see many people just copy-past code from article into their solutions. The code I gave in previous post has been changed drastically, but instead of re-writting original post I decided to create new one.

Latest version of ELMAH MVC controller

So, after all modifications it looks like:

namespace ElmahMvc.Areas.Admin.Controllers {
    class ElmahResult : ActionResult {
        private string _resouceType;

        public ElmahResult(string resouceType) {
            _resouceType = resouceType;
        }

        public override void ExecuteResult(ControllerContext context) {
            var factory = new Elmah.ErrorLogPageFactory();

            if (!string.IsNullOrEmpty(_resouceType)) {
                var pathInfo = "/" + _resouceType;
                context.HttpContext.RewritePath(FilePath(context), pathInfo, context.HttpContext.Request.QueryString.ToString());
            }

            var currentApplication = (HttpApplication)context.HttpContext.GetService(typeof(HttpApplication));
            var currentContext = currentApplication.Context;

            var httpHandler = factory.GetHandler(currentContext, null, null, null);
            if (httpHandler is IHttpAsyncHandler) {
                var asyncHttpHandler = (IHttpAsyncHandler)httpHandler;
                asyncHttpHandler.BeginProcessRequest(currentContext, (r) => { }, null);
            }
            else {
                httpHandler.ProcessRequest(currentContext);
            }
        }

        private string FilePath(ControllerContext context) {
            return _resouceType != "stylesheet" ? context.HttpContext.Request.Path.Replace(String.Format("/{0}", _resouceType), string.Empty) : context.HttpContext.Request.Path;
        }
    }

    public class ElmahController : Controller {
        public ActionResult Index(string type) {
            return new ElmahResult(type);
        }
    }
}

How to use it in my application?

Easy. Install ELMAH by NuGet, in package console

 Install-Package elmah

It is optional (but preferable) to create new Area called Admin. Inside AreaRegistration.cs your should place routing for ELMAH controller:

context.MapRoute(
        "Admin_elmah",
        "Admin/elmah/{type}",
        new { action = "Index", controller = "Elmah", type = UrlParameter.Optional }
    );

Create ElmahController.cs (just from code above) and place to yours Areas/Admin/Controller folder, add file to project. Don’t forget to change the namespace according to your project.

Configure ELMAH logging options (Memory, XML, SQL), use Web.Config of this project as example. Run application, and see that:

 /admin/elmah

works.

Optional (but very preferable) is to secure your controller with Authorize attribute:

 [Authorize(Users = "Admin")]
 public class ElmahController : Controller
 {

That’s it.

Known issues

One current known issue - if I’m using SqlErrorLog as error log class and press “Download log” button on ELMAH dashboard, you’ve got empty result. Unfortunately, it does not work now, since issue in ELMAH core that I hope will be fixed in nearest release.

NuGet package for it?

I didn’t expect such popularity of that class, but now I seriosly think putting this on NuGet. I’ll try to package that as soon as possible.

Inside ASP.NET MVC: IResolver and it’s implementations

One of the major changes between MVC2 and MVC3 was introduction of Dependency Injection principles on a level of framework. If you compare, for instance ControllerBuilder.cs from MVC2 and ControllerBuilder.cs from MVC3 you will clearly see the difference. In MVC3 we are no longer create entities directly (through ‘new’ operator), but instead we delegate that to IResolver interface. IResolver interface itself is extremely simple:

namespace System.Web.Mvc {
    internal interface IResolver<T> {
        T Current { get; }
    }
}

We can just ask the instance of type we would like to resolve. Please also note, that IResolver is internal class, so it is not exposed and you will never use it in application directly.

All major entities of MVC framework (ControllerFactory, Filters, ViewEngines etc.) from now resolved by IResolver implementation class. That improves extensibility of framework very much and introduces new strategy of creation objects.

Implementations of IResolver interface

There are two classes that implements IResolver - SingleServiceResolver and MultiServiceResolver. Primary responsibility of those are delegation call to IDependencyResolver methods GetService and GetServices, respectively.

If they just recalling method of IDependecyResolver class, what’s are the purpose of those two classes?

There are 2 purposes I can see:

  1. To provide default type instance in case of type is not resolved by IDependencyResolver.
  2. To create instance only once.

How it works?

Now, let’s take a look how it actually works. It is really simple and small, so I’m able to put most of code here.

Construction:

public SingleServiceResolver(Func<TService> currentValueThunk, TService defaultValue, string callerMethodName) {
 if (currentValueThunk == null) {
  throw new ArgumentNullException("currentValueThunk");
 }
 if (defaultValue == null) {
  throw new ArgumentNullException("defaultValue");
 }

 _resolverThunk = () => DependencyResolver.Current;
 _currentValueThunk = currentValueThunk;
 _defaultValue = defaultValue;
 _callerMethodName = callerMethodName;
}

You can see, it receives default factory method, default type instance and the name of caller method (used as additional information in exception).

Here, how ControllerBuilder creates the SingleServiceResolver, for instance:

internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver) {
 _serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
  () => _factoryThunk(),
   new DefaultControllerFactory { ControllerBuilder = this },
  "ControllerBuilder.GetControllerFactory"
 );
}

Since it implements only one property, current Current:

public TService Current {
 get {
  if (_resolverThunk != null) {
   lock (_currentValueThunk) {
    if (_resolverThunk != null) {
     _currentValueFromResolver = _resolverThunk().GetService<TService>();
     _resolverThunk = null;

     if (_currentValueFromResolver != null && _currentValueThunk() != null) {
      throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.SingleServiceResolver_CannotRegisterTwoInstances, typeof(TService).Name.ToString(), _callerMethodName));
     }
    }
   }
  }
  return _currentValueFromResolver ?? _currentValueThunk() ?? _defaultValue;
 }
}

First, we check the existence of _resolverThunk it would always exist (having value of () => DependencyResolver.Current) for first call of the method. Then, we locking on _currentValueThunk protecting for multiple threads access the same method, same time. Then, we try to resolve given type by asking _resolverThunk() to GetService<TService>().

After that we have an if-statement that I didn’t get from the very beginning. Fortunately, MVC project has bunch of good unit tests. As I found the test it turns clear to me. The test called CurrentThrowsIfCurrentSetThroughServiceAndSetter and it’s Assert part:

[TestMethod]
public void CurrentThrowsIfCurrentSetThroughServiceAndSetter() {
 // Arrange
 TestProvider providerFromCurrentValueThunk = new TestProvider();
 TestProvider providerFromServiceLocation = new TestProvider();
 TestProvider providerFromDefaultValue = new TestProvider();
 Mock<IDependencyResolver> resolver = new Mock<IDependencyResolver>();

 resolver.Setup(r => r.GetService(typeof(TestProvider)))
   .Returns(providerFromServiceLocation);

 SingleServiceResolver<TestProvider> singleResolver = new SingleServiceResolver<TestProvider>(() => providerFromCurrentValueThunk, providerFromDefaultValue, resolver.Object, "TestProvider.Current");

 //Act & assert
 ExceptionHelper.ExpectException<InvalidOperationException>(
  () => singleResolver.Current,
  "An instance of TestProvider was found in the resolver as well as a custom registered provider in TestProvider.Current. Please set only one or the other."
 );
}

This is really important and says: you should not create same type instance both with IDependencyResolver and factory method! In case of ControllerFactory: you should never provide your implementation of IControllerFactory and in the same time resolve IControllerFactory instance by IDependencyResolver. Same rule for all other types. You should decide how you would like to override default behavior. In MVC3 usage of IDependencyResolver is a preferable.

The code below is wrong:

DependencyResolver.SetResolver(new DummyDependencyResolver());
ControllerBuilder.Current.SetControllerFactory(new DummyControllerFactory());

So, after that _resolverThunk is reset and we no longer ask IDependencyResolver, just returning the resolved value.

MultiServiceResolver is even a little simpler.

public IEnumerable<TService> Current {
 get {
  if (_itemsFromService == null) {
   lock (_itemsThunk) {
    if (_itemsFromService == null) {
     _itemsFromService = _resolverThunk().GetServices<TService>();
    }
   }
  }
  return _itemsFromService.Concat(_itemsThunk());
 }
}

The same, singleton strategy of resolving types and then just concatenating resolved by IDependencyResolver with ones retuned by default factory method. It looks strange, but it is legal here to have types resolved both by IDependencyResolver and factory.

Conclusions

IResolver, SingleServiceResolver and MultiServiceResolver are all internal parts of framework. We are not directly using any of them. They used as kind of bridge between previous (MVC2) object creation strategy and new (MVC3) one. New strategy is using Service Locator (IDependencyResolver). It is important that we should never ‘mix’ both in the same application. Preferable way is IDependencyResolver.

What’s next?

We are going to continues our journey of resolving types and meet IDependencyResolver closer.

Previous Inside ASP.NET MVC: ControllerBuilder class

My application for 10KAppart competition

Recently, I’ve met really interesting competition by @mixonline called 10K Appart. Due to the rules, you have to create an application total size of which should not be more than 10K zipped content. Moreover, it have to be pure client-side application, utilizing HTML5/CSS3 features for responsible design and open API for gathering data. No frameworks, no 3rd parties. I decided to participate.

I’ve spent several hours to catch up idea. I was thinking about some application for twitter or gmail, but finally I stopped on github. First of all, github is my favorite service, it has clear and open API. Last year I contributed to javascript github-api, so I knew how to start. Application idea is simple: analyze github account and based on actual achievements (number of repos, forks, issues etc.) assign corresponding badge.

I did it a style of weekend project, started up Friday evening, I’ve spend 3 hours to complete github API adapter and application logic. As always, hard part was - design.

Even I a bit improved my design skill through this year.. still it is big challenge. I choose light blue color for main color and dark blue as auxiliary. I went with Google Web Fonts that I used before and was happy with results. Playing out with colors and gradients, I came up with such front page:

code

With much help of Sasha we have designed badges part of application. I still not 100% happy, but at least it was quite fast.

code

After application were more or less ready, I put it on temporary hosting asking my dear twitter help me to validate it. I received a lot of great feedback (thanks a lot, guys). After all bugs were fixed, I posted my entry to 10K appart.

I’ve been waiting about 4 days, to receive an answer. Meanwhile, I’ve seen that new application are being posted.. but not mine. Finally, they responded to me saying “Sorry, but Google Web Fonts are not allowed”. That was actually my bad, but I haven’t thought that are treated as 3rd party. Anyway, I had to switch to TypeKit very fast. I didn’t get same results as with Web Fonts, but I had no time for finding perfect match and reapplied again.

It finally available here - http://10k.aneventapart.com/Entry/Details/512

I would be happy if you try it, tweet it, comment on site. Sources are placed on github, so If you think to improve design or create new type of badge, you are welcome!

IT Jam 2011 in Odessa

IT Jam is a conference for developers in Ukraine. Highly popularized through the last years now it became the most popular IT events in Ukraine. The slogan of conference is “Meet & Mix” saying it’s primary goal is to create good conditions for networking and experience sharing.

I’ve never been visiting IT Jam before. But this time, I not only visited but have a speech there. Moreover, the company I work to was sponsoring .NET section.. and I got a honor to be a representative there. I’ve started to prepare on a very short notice, just 5 days before conference.. all of these facts let me a little nervous.

We decieded to go by car, with my great colleagues @korneliuk and @VladAlieks. Having a good company is a key for any trip. I haven’t noticed how fast we came to Odessa. We stopped in Odessa’s Alpine club where I used to spent great summer days during my rollerblading career. We’ve got there late evening, so had a time only to install our tent, say hello to the sea and fall asleep.

Next morning we have a breakfast and moved to the place. IT Jam took biggest area in Odessa, Odessa’s See Terminal. That was really cool, since there you definitely could feel the spirit of Odessa - sea breeze, sun, ships. Marina Vyshegorodskikh and Alexandra Chudner who opened the event, energized the crowd for the rest of the day.

I’ve spent most my time mostly in .NET section. IT Jam format of speeches are supposed to be short. That was something that I didn’t expect at the begining, so after the schedule been published I realized - it is just impossible to fit everything I want to say in such short period of time. Anyway, I had no option and have to start my speech.


Alexander Beletsky on IT Jam


Olga Didich did a great job helping out all speakers and timekeeping. So, I just step by on scene and started up. As always it’s quite hard to describe and show the code for such big crowd, but I tried the best. Of cause, I haven’t managed to accomplish all my speech.. but I was really happy that people were contacting me a lot of questions, just after it. We were sitting together with one guy after and I was showing the rest of my presentation just for him :).

As “Meet & Mix” format supposed, I had really nice talks with other developers. Ones, that I worked many years ago.. or ones we’ve met just recently.. or one’s we following each other in tweeter but had no chance to meet offline :). So, @dimapasko, @ChuniMuni, @xpinjection, @chaliy, @antonvidishchev, Dmitry Davydov - guys, it very nice to see you there.. Thanks for your company and great beer-n-talks we had together.

At the evening I’ve met my old friends from Odessa and all our company moved back to Alpine club, to have a swim, drink and guitar playing on beach for all night. That was just amazing conclusion of that day.

I want to say big thanks, for everyone who involved in organization. Keep doing great job and improve from year to year. And for my friends who were always nearby, supported me and didn’t allow to be bored.

Analog of SVN branch switch for Git

Working with Git in SVN based organization is possible and make a lot of benefits. Sources checked out once are now at you local repository, so all you do is commits, rebases and dcommits back to SVN. But sometimes you need to be able to switch to another SVN branch. You need something equivalent to “SVN switch” command inside Git environment.

I’m been trying to switch to new branch, but I found no related information about that. I ended up this solution, I would like to share.

  1. Manually add new configuration into ~/.gitconfig, for new SVN location
  2.     [svn-remote "svn25"]
            url = https://svn.server/branches/branch25
            fetch = :refs/remotes/git-svn-25
    
  3. Fetch changes from svn25
  4.     git svn fetch svn25
    
  5. Checkout that branch
  6.     git checkout git-svn-25
    
  7. Create new “master” branch
  8.     git checkout -b master-25
    
  9. Now, master-25 is your “master” for branch25 SVN branch.

You can merge you previous changes.. and continue to work with master-25 as you worked with usual master.

How to be better developer or 3 accounts rule

Oh no, not again! - you might think. Yet another Mr.SmartyPants are going to share his own vision of how to improve in development.

I’ll say very obvious thing - if you are going to be great in something, you have to do that a lot. Like, if you going to be a great snowboarder you have to ride a lot; If you going to be great mathematician you have to solve a lot of problems; If you going to be great developer you simply have to do a lot programming :).

The road from “good to great” is long and difficult, you could not be great in one year.. or ten, or even whole life. But what you definitely can do, be a better. Only realizing that you are better than yesterday (month, year ago) is a great benefit, believe me.

But just the fact of knowing “I need to do something a lot” would hardly could help you to progress. What you need to have is indicators. Simple criteria’s that make you understand what your progress is. Are doing great or you suck?

Three account’s that I created almost year ago, help me to get those indicators.

  • github.com - producing of code, that what we do. you have to have github to store all code you produce, doesn’t matter it is a product or tool or just a gist you created to help someone - it have to be stored. with a github you should be able to see how much you coding are changing through the time. you should review you last year code and think “Oh, God I suck a lot!”.
  • blogger.com - besides of code writing, you have to share your technical thoughts. the blog, is a great motivator for seeking and sharing knowledge. as well as coding, blogging requires much skills. I see some relation between producing good code and good post. blog would also help you to look back, to remind you problems you was thinking of.. and how much you were right on that? is your opinion changed on some topics or not?
  • stackoverflow.com - if you can’t explain something to another, you don’t understand it. giving an answers is extremely difficult, especially in such competitive environment as stackoverflow. the time I created account there I was not able to give any answer in meaningful time. I just had not enough skills for that. stackoverflow is great indicator, since it contains a reputation system.

Well, do you think it is useful? It works for me and I’m going to proceed.

PS. That’s my 100 post for this blog.. and that’s my Friday before week vacation.

A little bit on Javascript magic inside C# code

C# and Javascript are both my favorite languages. I believe that those two are best languages in a world (perhaps I haven’t started to learn Ruby). With a quite long practice in Javascript, you start to feel real power of dynamic language. Even more, you are so much get used for particular code constructions that you try to do the same things in C#.

This is something you might do in javascript a lot. Consider that code,

code

Method createConfig takes options object, dynamically construct config object and returns it back to client. Maybe it is the best example, but shows - I dynamically able to construct an object, just putting new properties into it.

Now, let’s try to do that same with C#. Believe me or not, but I can do exactly (OK, mostly exactly) code with C#.

code

We can play “Find a difference” game here. Anyway, what I can say: “anonymous types + dynamic + ExtendoObject”, is a magic spell that turn you C# code into Javascript.

  • With Anonymous Types you easy get a notion of JavaScript dynamic object, just use new { MyProp = 1 } JavaScript analog { MyProp: 1 }.
  • Dynamic would tell to compiler - “Do not check my type now, let Runtime do that”. So, with dynamic objects you can do obj.MyProp, compiler would allow this code, existence of property would be checked on runtime, if absent - exception will be thrown.
  • ExpandoObject is a super-power of .NET, allows you to construct object at runtime. You can see, that I just assign new property, that property would be dynamically added to config object.

Life would not be so interesting if every thing is so easy. My first implementation failed to work, in line if (option.Ip || option.Proto) then I called createConfig with object that actually contains no such properties. As I said above, dynamic simply throws an exception if property is missing. I could wrap code in some try / catch cases, but it would be to ugly and magic would gone. We have to extend our magic formula with one component - Reflection. So, let’s pronounce spell again, “anonymous types + dynamic + ExtendoObject + Reflection” and check out final secret piece of code.

DynamicProxy is simple wrapper around the dynamic, it overloads [] operator and check availability of property using Reflection.

code

That’s it. I’ve made C# code look like and behave like JavaScript, utilizing power of .NET platform. As always, you can find a source code on github - csharp-js.

Disclaimer

You should not probably doing such tricks a lot. C# is still static language (even with dynamic features in it). It is better to rely on types, wherever it is possible to.. The code above is created to solve my particular problem and I had a lot of fun detecting this C# and JavaScript analogy. But now I still thinking to re-write that to statically typed less-beauty, less-magic solution :).

Switching from ASPX to Razor view engine

I’ve been moving my application to MVC3 quite time ago. There was absolutely no issues of migration, everything that worked OK in MVC2 worked fine with MVC3. One of major feature that MVC3 brings with is Razor. Razor is view engine which combines HTML and code in very elegant fashion. Just from first sight to Razor you begin to understand how much ASPX sucks (I don’t blame ASPX since it has been designed for WebForms, actually.. and it just does not fit MVC much).

Of cause, till that time I had a lot of already made markup with ASPX. I have register task to switch all my views to Razor. But for a long time it’s being un-touched, I just been either doing some other things or too lazy for that kind of job. Yes, it is not very exiting to change *.aspx to *.cshtml.. Finally I put all my will on that, thinking better late than never.

And you know, it was not so difficult and boring as I originally thought. Here are some obvious tips:

  • Rename file from *.aspx to *.cshtml
  • If you have master page like (Public.Master) change it to _PublicLayout.cshtml (Razor don’t use term Master, but rather Layout)
  • <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Web.Models.LastArticleFromBlogModel>" %> became @model Web.Models.LastArticleFromBlogModel
  • <asp:ContentPlaceHolder ID="head" runat="server"/> became @RenderSection("Head", required: false) in Layout pages
  • <asp:ContentPlaceHolder ID="maincontent" runat="server"> became @RenderBody() in Layout pages
  • <%@Import Namespace="Web.Helpers.Extensions" %> became @using Web.Helpers.Extensions
  • <%: are changed to @ and %> changed to nothing (I simply used Find&Replace for that)
  • At the top of content page
    @{
     ViewBag.Title = "Admin | Admin Dashboard";
     Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
    }
  • For content pages, everything that is inside is Body (no special sections for that)
  • If you need to override Head section, simply @section Head { }
  • Layout could be nested, in nested Layout page you should mention parent Layout, like above

That’s basically it.. Along the way I’ve changed all HTML to comply HTML5 standard and reformatted (with Ctrl K + Ctrl D) and now markup looks definitely better!

One really strange issue I should mention. As soon as I finished and pushed code to github my friend Jenkins immediately picked up changed and deployed them. But I as went to check it, I got 404 Error just from very beginning. After investigation I found the reason - as I was just renaming files *.aspx to *.cshtml, in *.csproj (project file) all of them are became in “None” item, instead on “Content”.. and site publishing just ignored that items. I have to manually change it back, as soon as I committed, it started to work like charm.

So, there are no any technical issues with moving from ASPX to Razor, just don’t be to lazy and do it today :)

Git with SVN, what the benefits are?

My previous post about starting up of using Git inside on SVN organization appeared to be really attractive, I received many questions through twitter and dzone. All of them are really interesting and I going to do a separate posting on that, but primary question is “Why, oh why?”.

So, what actual benefits I see by using approach of git-svn?

First, let’s see the root, what kind of VCS Git is? It is distributed one. The distribution basically means that each developer host the repository on it’s own machine. Not a working copy as in SVN case, but real repository with all corresponding functionality - commits, reverts, branches, merges etc. You are not longer depend on server, even if sever is not available you still able to continue your job.

Since you have your local repository, you can do whatever you want without interfering the rest of the world. In SVN all operations like commit or branch creation or tag - they are global one. As soon as you created branch for instance, everybody will notice that; if you committed something, everybody will notice that. In many organizations SVN has policies, like you have access only for some branches.. you can’t create branches, only by request to admin etc. But, what I basically do on my job - I want to try out something (new idea or apply some refactoring) without disturbing a lot of people, I want that quickly. It perfectly works with Git, I create the branch just by one command, work inside (means do what ever number of commits I want) and if I think I’m ready, merge it back to master and push changes to SVN.

Remember you last merge operation with SVN? If you haven’t seen ‘Tree conflict’ type of conflict, you are not SVN user. I’ve seen them a lot and many people suffer much of it! This type of conflict happens because SVN keeping and tracking information about folder in which file is placed. Git does not do that, it is basically content tracking system - Git cares about content of the file, not file it self. Since the information about content (blob) and filesystem information (tree) is separated each of other, you will never get a ‘Tree conflict’ in Git.

By the fact that branches and merges are very easy in Git you are getting one really cool bonus. Have you ever been in situation then in a middle of your flow, then tens files are already changed, but you still struggling with task, your boss is contacting you saying - ‘Hey, we have critical bug, required to be fixed now’? Such things make you a little uncomfortable, you already got some changes, but they are not ‘commitable’.. you could not throw it away, because some value is already there, but you need to get SVN update and start to fix bug. With git, you can switch from one task to another with out any problems. You just commit your results (even if they are not compliable or tests are red, who cares - it’s yours repository) create another branch for bugfix and start to work.

To summarize that a little I would say that my personal benefits of starting using Git are:

  • Isolation - do whatever I want, whenever I want
  • Merges - forget about ‘Tree conflicts’
  • Task switching - no more, “please wait till I commit this, so I can start to work on that”
  • Fun - it is interesting to me to learn new system and to change a mind how VCS can work

Inside ASP.NET MVC: ControllerBuilder class

Integral part of MvcHanlder is ControllerBuilder. ControllerBuilder is a singleton that is responsible to produce IControllerFactory instance.

controller builder

Construction

ControllerBuilder have 2 constructors, the default one and one with parameter. One of the major changes between MVC2 and MVC3 was the improvements of Dependency Injection. MVC is using Service Locator pattern for resolving dependencies.Default constructor calls constructor with parameter, passing null as argument, saying that SingleServiceResolver object have to be used as default service resolver.

Please note, even if MVC is using Service Locator to locate different entities (like Controllers, Views, Filters) and so on, it does not include any kind on IoC frameworks itself.

Controller factory get/set

MvcHanlder uses GetControllerFactory method to get controller factory.

controller builder

Method itself is fairly simple, it just ask service resolver to get current instance of controller factory.

Setter method allows you to change default controller factory with custom one. This an extremely useful then you want to change the way of Controller creation. The most useful case is delegate the controller creation to some DI container (Ninject, Unity, StructureMap) to allowing your application to get benefits of using IoC principles.

Basically, IControllerFactory is a strategy of controller creation. Depending of implementation it might use different techniques, later on we will see how DefaultControllerFactory works.

As and additional option, it is possible to supply custom controller factory just from the specific type

controller builder

Substitute default controller factory

As you see, we have to options of substitution default factory:

  1. Call SetControllerFactory method and pass custom object into.
  2. Implementing new IDependencyResolver.

Here is an example of how that could be done (please note, it is just demostartion.. you typically should not use both approaches in the same type).

controller builder

Conclusions

ControllerBuilder is simple class that delegates responsibility to IResolver which is responsible to resolve IControllerFactory instance. IControllerFactory is a strategy of controllers creation. ControllerBuilder is designed in a way of chaning this strategy easily, either by using custom IControllerFactory or by custom IDependencyResolver.

What is next?

Next we are going to look closer into SingleServiceResolver and see how it actually acts for resolving types.

Previous: Inside ASP.NET MVC: All begins here - MvcHanlder