My attempt to use Composite Web Application Block with ASP.Net MVC Application



By ganton ~ November 20th, 2008. Filed under: ASP.Net.

Let’s say that there is an application written in ASP.Net MVC and that there is a  need to make it composite. I’ve searched the Interenet and I didn’t find so much about how to do it. For sure using Web Client Software Factory (WCSF) it can be done but it is not suitable for my case. And then i found an article by David Hayden. This gave me an idea to try to do this my self and to see what will have on the end.

Here I’d like to present you the standard ASP.Net MVC application which is generated when you create an ASP.Net MVC application using Visual Studio. I’ve just reorganized it a bit in order to add into it Composite Web Application Block (CWAB). Let me say that this block is the core of the WCSF and it is created in order to cover its needs but using it as an infrastructure I think we are able to create an ASP.Net MVC application composite.

You can download the source code from here.

The first what I’ve did was to create a new MVC application and to add Microsoft.Practices.CompositeWeb.dll, Microsoft.Practices.CompositeWeb.EnterpriseLibrary.dll, Microsoft.Practices.ObjectBuilder.dll into its root folder (in a separate directory :)). I add three additional libraries into my solution Utils, Shell and HelpModule. It is depicted at the picture below.

The Utils library is not used as a business or foundational module but it contains class used in my application to register my own information about modules. ModuleMenuInfo class is an info class which contains module information that I use in web application.


public class ModuleMenuInfo
{
public string Key { get; set; }
public string Title { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
}

The second class is ModuleMenuManager which manages module information. It allows adding, removing a module and retrieving all available modules.


public class ModuleMenuManager : IModuleMenuManager
{
private IDictionary<string, ModuleMenuInfo> _modules;

public ModuleMenuManager()
{
_modules = new Dictionary<string, ModuleMenuInfo>();
}

#region IModuleManager Members

public void AddModule(ModuleMenuInfo moduleInfo)
{
// code ...
}

public void RemoveModule(ModuleMenuInfo moduleInfo)
{
code ...
}

public IEnumerable<ModuleMenuInfo> GetModules()
{
return _modules.Values;
}

#endregion
}

[sourcecode]

Then I've created a module named Shell which is a required module for the application at whole. All additional modules depend on it. Normally, it should contain registration of any global services and other configuration operations. In my case I use it only for registering ModuleMenuManager class as a global service in order to use it in other modules for registering their selves. in addition, It registers itself to ModuleMenuManager because I need to display initial information in the shell. In a standard WCSF application it is a functional module and it doesn't have any connection with the web site. In my case it is the same but it just adds some information used by presentation layer.

[sourcecode language="csharp"]

public class ShellModuleInitializer : ModuleInitializer
{
private IModuleMenuManager _moduleMenuManager;

public override void Load(CompositionContainer container)
{
base.Load(container);

AddGlobalServices(container.Parent.Services);
RegisterSiteMapInformation();
}

protected virtual void AddGlobalServices(IServiceCollection serviceCollection)
{
_moduleMenuManager = new ModuleMenuManager();
serviceCollection.Add<IModuleMenuManager>(_moduleMenuManager);
}

protected virtual void RegisterSiteMapInformation()
{
_moduleMenuManager.AddModule(new ModuleMenuInfo()
{
Key = "Shell",
Title = "Home",
Controller = "Shell",
Action = "Index"
});
}
}

As you can see ShellModuleInitializer inherits from ModuleInitializer class. It is a class from CWAB and each module should implement a class which inherits from him in order to register its services, types or whatever it needs to do at the time of module initialization.

The second module that I’ve created is a business module named HelpModule. It doesn’t contain any special functionality but a simple class named HelpLogic which only returns a method that returns a title name.


public class HelpLogic
{
public string GetTitle()
{
return "About Page";
}
}

It also has its own HelpModuleInitializer class where it retrieves an instance of IModuleMenuManager and use it in order to register its self.


public override void Load(CompositionContainer container)
{
base.Load(container);
RegisterSiteMapInformation(container.Parent.Services.Get<IModuleMenuManager>(true));
}

Finally, modules of my composite MVC application are ready for use and I can change the standard MVC application in the way that it will behave as a composite application. First of all I went to global.asax.cs file and change it as it is shown below.


public class MvcApplication : WebClientApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default",                                              // Route name
"{controller}/{action}/{id}",                           // URL with parameters
new { controller = "Shell", action = "Index", id = "" }  // Parameter defaults
);

}

protected override void Start()
{
base.Start();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new CompositionControlerFactory());
base.AddRequiredServices();
}
}

I’ve change it to inherit from WebClientApplication file which is a class from CWAB which inherits from HttpApplication and extends it. Further, I delete Application_Start method and override Start method of WebClientApplication. It is executed only once when the application is started. There I registered the routes and I set my custom controller factory. AddRequiredServices of WebClientApplication registers all missed services used of CWAB.

CompositionControlerFactory class I need for executing WebClientApplication.BuildItemWithCurrentContext in order to build up the controller class requested and it will use ObjectBuilder to inject all dependencies a controller needs.


public class CompositionControlerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType != null)
{
object controller = Activator.CreateInstance(controllerType);
WebClientApplication.BuildItemWithCurrentContext(controller);
return controller as IController;
}
return null;
}
}

Further, I needed a BaseController class for getting all registered modules information and put it into ViewData. You can note that it has a property which holds an instance of IModuleMenuManager and that this property is decorated with ServiceDependency attribute from CWAB. Re-writing GetControllerInstance of DefaultControllerFactory I call WebClientApplication.BuildItemWithCurrentContext which will build up and inject needed class. But here I use ServiceDependency which tells CWAB that I need a service. Here I’ll get into ModuleMenuManager property a singleton of target class because I registered it as a global service and because I use ServiceDependency attribute. If I needed an unique instance for my controller I would use CreateNew attribute instead of ServiceDependency attribute.


[HandleError]
public class BaseController : Controller
{
[ServiceDependency]
public IModuleMenuManager ModuleMenuManager { get; set; }

protected void PresetMenuInfo()
{
foreach (var item in ModuleMenuManager.GetModules())
{
ViewData[item.Key + "_module"] = item;
}
}
}

I also created a HelpController class which is connected with HelpModule business module. Note that here I use CreateNew attribute in order to tell CWAB to build up for me a new instance of HelpLogic class each time I create HelpController.


public class HelpController : BaseController
{
[CreateNew]
public HelpLogic HelpLogic { get; set; }

public ActionResult About()
{
base.PresetMenuInfo();

ViewData["Title"] = HelpLogic.GetTitle();

return View();
}
}

Finally, I changed a bit the master page of the application in order to analyze the information from ViewData and according to it to add and remove menus.


<ul id="menu">
<%
if (ViewData["Shell_module"] != null)
{
Utils.ModuleMenuInfo shellModule = (ViewData["Shell_module"] as Utils.ModuleMenuInfo);
%>
<li><%= Html.ActionLink(shellModule.Title, shellModule.Action, shellModule.Controller)%></li>
<%
}
if (ViewData["Help_module"] != null)
{
Utils.ModuleMenuInfo helpModule = (ViewData["Help_module"] as Utils.ModuleMenuInfo);
%>
<li><%= Html.ActionLink(helpModule.Title, helpModule.Action, helpModule.Controller)%></li>
<%
}
%>
</ul>

Oh, I almost forgot to share that I also change Web.config file of the application where I’ve added information that CWAB uses to register my Shel foundational module.


<compositeWeb>
<modules>
<module name="Shell" assemblyName="Shell" virtualPath="~/"/>
</modules>
</compositeWeb>

I’ve also changed the Web.config file which is placed into Views folder. There I’ve added information about HelpModule business module. Note that it has a tag dependencies where one can list all modules the current depends on.


<compositeWeb>
<modules>
<module name="HelpModule" assemblyName="HelpModule" virtualPath="~/Views/Help">
<dependencies>
<dependency module="Shell" />
</dependencies>
</module>
</modules>
</compositeWeb>

I hope that you note virtualPath attribute in both XML snippets. It is not used in any case in this realization but it is used by CWAB and without it it will not work properly.

And now let me show two screens one when HelpModule module is registered via Web.config and one when it doesn’t registered. Below is the first snapshot where you can see two menus home and about.

And here is the second snapshot with only one menu attached because HelpModule module is not registered in the configuration file.

My custom Visual Studio’s environment settings



By ganton ~ November 19th, 2008. Filed under: Other.

I’m using non-standard Visual Studio environment settings and I’ve decided to share them with other developers on the web. I hope that everybody is familiar with how to import and export VS settings but for those who do not know I’ll write few words.

First of all you need to start your VS :). Then you should go to Main menu\Tools\Import and Export Settings…

Visual Studio Import and Export Settings Wizard will appear. You can follow wizard instruction and you will be able to import, export or restore defualt settings.

And now let me show you some print screens with different VS’ text editors and their look. Below you can see my XML editor settings.

The next screen shot depicts the settings of my HTML editor.

And below you can look at my settings of C# language text editor.

I also use the same line of colors and fonts in order to configure VS immediate window and find result window. Below is the find result window.

And now if you like my VS environment settings you can download them from here and use them. This package contains only my editors settings and will not change your toolbox or other windows position. It also will not change your text editor formatting settings. But I strongly RECOMMEND you to export your current settings before to import my settings in order to be able to restore your preferred VS state in the case you do not like my settings when you touch them.

Enjoy!

I have new theme applied to my blog



By ganton ~ November 18th, 2008. Filed under: Wordpress.

Some time ago, I saw that my blog doesn’t look well on browsers different from Mozilla. As it was clear it was because of the theme used.

Yesterday, I looked for a theme that I’ll like and that it will look more or less good at least on IE6, IE7, Mozilla and Chrome. And I choose Bytetips 1.6 by Jim. I changed the body background color and make it to have a fixed size. I also remove the image from the header for now. Few simple things  but I like the theme like it looks on my blog. May be I should center it but I didn’t decide it yet.

Thanks to Jim for the nice theme. Well done Jim!

Enterprise Library 3.1 installation problem



By ganton ~ November 17th, 2008. Filed under: Other.

I needed to install Web Client Software Factory (WCSF) on one old machine which I decided to use for some tests. As far as WCSF needs Enterprise Library 3.1 I’ve decided to install it. And I ran into a problem.

Firstly, let me say what I have installed on the machine. OS - Windows XP SP, VS 2008, Guidance Automation Extensions (GAX) and Guidance Automation Toolkit (GAT) for VS 2008.

So, before to install WCSF I’ve tried to install Enterprise Library 3.1 and I got the error below.

The error says that some types cannot be loaded. That’s why I’ve started fuslogvw.exe from the SDK and tried to see what went wrong.

The last log record has information about the error that has occurred during installation. It was clear from the log that for some reason Microsoft.Practises.RecipeFramework.dll cannot be loaded.

Than what came into my mind was that it is somehow connected with GAT and GAX. Logically, I thought that I have installed newer version of both on my machine and may be it can be the reason. And I’ve tried to uninstall both GAT and GAX. After uninstalling them I’ve tried to install Enterprise Library 3.1 again. And it was installed without any problems.

Have fun!

The power of unit tests



By ganton ~ November 10th, 2008. Filed under: Unit testing.

What i’d like to share with you is that the unit tests are really power and they make developers life much easier. I saw a lot of developers that said that unit testing is just a spent time in not right direction (developing code). As I remember in the beginning I also was in this group of wrong believers. But after a while I became a developer who thinks that without unit testing the code is hard to test and it is most likely not well formed. I hope everybody agrees that the use of TDD makes the code much more structured and well formed.

I’d just like to give you an example of how unit tests help us to not miss trivial errors. Last week in our team we saw that we need to extend one of our external modules with a new functionality. Before to extend it I realized that the module needs to be re-factored in order to extend the one abstract base class and to remove some common functionality from its descendants. It was done. Unit tests for the new functionality were written and the new functionality was implemented. And I ran the tests. What happen? More then 60% of our module unit tests doesn’t pass well. And the reason was a very trivial error which without unit tests I’ll found after integration of the module.

Conclusion, the unit testing is a part of software development that nobody should ignore. It will save time and efforts when you test your code and it will improve code quality. It is for sure.

I’m annoyed of how developers used to organize loops…



By ganton ~ November 4th, 2008. Filed under: Other.

Today, I browse the code of one of our projects in order to look through a problem I discussed with another developer and I saw a loop which irritated me. The sample of what I’m talking about is below.

object obj = null;
foreach (int item in array)
{
// initialize the object if the first pass
if (obj == null)
{
obj = new object();
}
// do some work
}

I really do not like when I found a loop where we have a check and after the check we initialize an object. I became even more irritated of the comment. But why to write such code? I didn’t found any reason for organizing the loop such a way. Why I do not like it? First of all because it is not well formed and if you have a more then 20 lines of code in the loop and another 5 in the if statement it becomes not exactly clear. The second and not the least thing is that it is slower with the if statement then without it.

I can offer several variants of how to do the same and it will work faster and the logic will be the same as it is in the cycle. The first variant is just to initialize the object before to go to the loop. The disadvantage of this variant is that if we initialize some heavy object it will take some time may be more then the time of all loop checks.


obj = new object();
foreach (int item in array)
{
// do some work
}

In the case we have a heavy object for initialization we can use the variant below.


if (array.Count > 0)
{
obj = new object();
foreach (int item in array)
{
// do some work
}
}

Of course we also can use a variant with IEnumerator. It is a very elegant snippet (see below) but it will get much more time then others because of the call of a function.


IEnumerator enumerator = array.GetEnumerator();
if (enumerator.MoveNext())
{
obj = new object();
DoWork();
}
while(enumerator.MoveNext())
{
DoWork();
}

I test the performance of all variants with an array of 10000000 entries and the results are below.

I know somebody can say come on man it is not so much time difference. Yes, I know that but in any case I do not like the initial variant because it is also not elegant and doesn’t look well. Of course, it is my opinion and everybody can write code in his/her way.