Alexander Beletsky's development blog

My profession is engineering

Sayonara Nippon

I’ve just got back from the most wonderful country I ever been to - Japan.


japan gates

Japan is really different from everything I got used to. Differences are everywhere, from traffic direction to people behavior. But in general Japan is well developed, high cultural country with interesting history.

Tokyo is huge, but the same is Tokyo Metropolitan which is really complex, but makes travel from one part of city to another very fast. First day we have a lot of problems to understand metropolitan labyrinths, but with a little practice it does not look so scary anymore. Btw, I’ve never seen very over crowded stations and trains, even if you travel in rush hour. Comparing to Kyiv metro, Tokyo one is very expensive, where you pay as much as you go.


tokyo metropolitan

People there are very kind, ready to help you. But the problem is communication. Very few Japanese can speak English. Usual dialog is something like. “Do you speak English?”, “A little..” and then nothing, even if you try to use as elementary words as possible. So, language barrier is very high. But as soon as they understood your problem, be sure you gonna get help. Once we’ve lost in metropolitan and one lady went out from station with ask, contacted metropolitan officer and explained our further actions. Such scenario happened several times.


noodles

Food is very delicious and relatively not expensive. Chinese and Japanese dishes are usually available together in restaurants. But if you want to go with sushi, you have to find specialized one. There are absolutely not a problem to eat in Tokyo. In each corner you could find small restaurants and cafeterias where you will be able to find what you like. Food is available mostly everywhere, including metro stations.


tokyo park

Tokyo is concrete and wires jungle, but there are several great parks inside. They are beauty and calm. It is easy to find a bench to sit and observe spectacular views. It is great to relax body and mind there.

I would not say I’ve seen a lot, but I really enjoyed with everything I saw.

Sayonara Nippon! Hope to visit you again in a while.. Best luck to you!

Using Ninject.MVC For Better ASP.NET MVC Integration

After the ASP.NET MVC infrastructure is ready, next logical step it to setup IoC container for application. Ninject setup is easy task, usually you solve that by implementation of your own ControllerFactory and put it to ControllerBuilder. As soon it is good enough approach it does not solve some important MVC implications, like injection of prosperities into filters. To make our lives a little easier Ninject team released Ninject.Web.MVC extension library that solves a lot of similar problems.

Getting binaries

Just follow the github to download latest version of Ninject.Web.MVC and place it to web site /Bin directory. No changes to web.config or something.

Tweaking global.asax

Now, let’s change global.asax according to Ninject.Web.MVC guidelines. I’ll just show how my current global.aspx looks like:

<%@ Application Language='C#' Inherits="Ninject.Web.Mvc.NinjectHttpApplication" %>
<%@ Import Namespace="Ninject" %>

<script RunAt="server">
 public void Application_Start()
 {

 }

 protected override void OnApplicationStarted()
 {
  AreaRegistration.RegisterAllAreas();
 }
 
 protected override IKernel CreateKernel()
 {
  var kernel = new StandardKernel();
  Sba.Web.Infrastructure.RegisterServices.For(kernel);
  
  return kernel;
 }

 public void Application_End()
 {
 }

 public void Application_Error(object sender, EventArgs args)
 {
 }
</script>

So, we basically inherit from NinjectHttpApplication class and override CreateKernel() method. You can see that inside the method I do call to RegisterServices - it is nothing more as static class, with For method that actually do the registration. Here is example:

using Ninject;
using Ninject.Web.Mvc;
using Sba.Common.Repositories;
using Sba.Sales.Models;
using Sba.Sales.Repositories;
using Sba.Sales.Repositories.ViewHandlerRepositories;

namespace Sba.Web.Infrastructure
{
 public class RegisterServices
 {
  public static void For(IKernel kernel)
  {
   kernel.Bind<ISessionLoader>().To<LazySessionLoader>();
   kernel.Bind<ILazyLoadChecker>().To<NHibernateLazyLoadChecker>();
   kernel.Bind<IDraftInvoicesRepository>().To<DraftInvoicesRepository>();
   kernel.Bind<IDraftInvoiceLinesRepository>().To<DraftInvoiceLinesRepository>();
   kernel.Bind<IPaymentTermsRepository>().To<PaymentTermsRepository>();
   kernel.Bind<IUnitsRepository>().To<UnitsRepository>();
   kernel.Bind<ICustomersRepository>().To<CustomersRepository>();
  }
 }
}

Injection the properties into filters

The main advantage of NinjectHttpApplication class usage, that now it handles the injection in different MVC entities by itself. For instance if you need inject to filter:

using System.Web.Mvc;
using Ninject;
using Economic2.Core;
using Sba.Common.Repositories;

namespace Sba.Common.Infrastructure.Filters
{
 public class SbaAuthorizeAttribute : AuthorizeAttribute
 {
  [Inject]
  public ISessionLoader SessionLoader { get; set; }

  public override void OnAuthorization(AuthorizationContext filterContext)
  {
            // some authorization logic here..
  }
 }
}

Integrating ASP.NET MVC Into Legacy Web Site

For some quite long time I naively thought that it is not possible (or at least very difficult) to make ASP.NET MVC stuff work on a Web Site project. But, my latest hacking of MVC opened another perspectives. There are no any difficulties with ASP.NET MVC on Web Sites. I’ll share an experience of integration ASP.NET MVC in my work project legacy Web Site.

Pre-conditions

In my case I integrated ASP.NET MVC2, since we are still running on .NET 3.5. If you are running .NET 4.0 the best is to go with ASP.NET MVC3 already. The difference of setup would not be huge, just in proper versions of assemblies.

I assume you already have ASP.NET MVC2 framework on your machine (if you have VS2010 - you definitely have one), if no just go that link and install it.

Web config changes

MVC assembly have to be added to web.config. Since the MVC infrastructure heavily depends on Routing mode, it have to be put to web.config as well.

Register MVC assemblies:

<compilation defaultLanguage="c#" debug="true">
 <assemblies>
  <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
  <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
  <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
  <add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

  <!-- Your application specific assemblies-->
        ...

  <!-- ASP.NET MVC -->
  <add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
 </assemblies>
</compilation>

Namespaces:

<pages enableViewStateMac="false" enableViewState="false" validateRequest="true" viewStateEncryptionMode="Never">
  <controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  </controls>
  
  <-- ASP.NET MVC -->
  <namespaces>
    <add namespace="System.Web.Mvc"/>
    <add namespace="System.Web.Mvc.Ajax"/>
    <add namespace="System.Web.Mvc.Html"/>
    <add namespace="System.Web.Routing"/>
    <add namespace="System.Linq"/>
    <add namespace="System.Collections.Generic"/>
    <add namespace="Microsoft.Web.Mvc"/>
  </namespaces>
</pages>

Register URLRouting module and handler.

<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules>
 ...
 
 <!-- ASP.NET MVC -->
    <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  </modules>
  <handlers>
    ...
 
 <!-- ASP.NET MVC -->
    <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </handlers>
</system.webServer>

Global.asax changes

You would be probably have global.asax without code-behind class. It’s not a problem, all you need is slightly change the Application_Start() method. Basically you can go and register routes there, as you do in any ASP.NET MVC application. But I didn’t do that. Instead, I used the advantages of Areas feature of MVC2, since it makes better logical grouping. So, my global.asax are:

public void Application_Start()
{
 AreaRegistration.RegisterAllAreas();
}

Models, Views, Controllers

In typical ASP.NET MVC application you have 3 folders, for - Models, Views, Controllers. Models/Controllers are C# code, views are .aspx pages. With a Web Site you typically place code into App_Code folder. But you should not do that. Instead, it it better to create a separate class library project that would hold your models and controllers. Views would be placed under corresponding Area folder.

New project for Models/Controllers

Just create a new class library project with such folder structure:


asp.net mvc class library

The most important - it should contain Area Registration class inside. This is the one that suppose to register all router for your application:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Sba.Web.Areas.Sales
{
 public class SalesAreaRegistration : AreaRegistration 
 {
  public override string AreaName
  {
   get 
   {
    return "Sales";
   }
  }

  public override void RegisterArea(AreaRegistrationContext context)
  {
            // All routes are here..

   context.MapRoute(
    "Sba_Sales",
    "sba/sales/{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
   );
  }
 }
}

That’s it. Now you implement Controller/Models in usual way and able to add unit tests project for new assembly.

Make sure that assembly will be placed into to Web Site /Bin folder. I simply added ../Site/Bin as project output directory. At the site initialization and Application_Start() call of Global.asax, all AreaRegistration instances would be created and routes being registered.

Views

Views have to be placed in the Web Site folder itself. MVC has several rules for views placements, so you have to follow them. Views for controllers that are part of Area’s have to be places into Site/Areas/AreaName/Views, the common stuff line master pages are in Site/Views/Shared. It is very important that each View folder must contain the web.config inside. You can either pick it up from default MVC2 application of just grab from gist.


views folder structure

IIS configuration

Our application previously worked in “Classic” mode. Even thought, it is possible to run MVC on “Classic” I would not really recommend it to do and if production environment allows, just switch you application pool to “Integrated mode”.


iis application pool config

After you did it, you can go and run you application. If you setup basic Home controller and view, you should be able to access it by given route. If you receiving 403 HTTP error check:

  • Are you really on integrated mode?
  • Are there any physical folders that the same as you routing, e.g /sba/sales route and /site/sba/sales folder? In such case you either should correct the routing or change site folder structure.

Session is Null issue

Moving along and starting implementation of some real controllers, we’ve got very strange NullReferenceException problem. After bit debugging it turned out that HttpContext.Current.Session is null in controller actions. That’s the common problem for legacy web sites. It is very well described in this stackoverflow answer. So, you just need to add one more section into web.config file.

<configuration>
  ...
  <system.webServer>
    ...
    <modules>
      <remove name="Session" />
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
      ...
    </modules>
  </system.webServer>
</configuration>

After all of those configuration changes your Web Site is fully adopted to ASP.NET MVC framework usage. So, just go ahead and feel the awesomeness of MVC!

Greg Young and Rinat Abdulin Visited Kyiv

It finally happened, Greg Young and Rinat Abdulin have been guesting Kyiv for almost the week.

Initially we’ve gathered on Beer && Code meeting. The format a little changed that time, but I would say that was really interesting meeting. Greg introduced one of the project he currently working on http://continuoustests.com/ that now referenced as “Mighty Moose”. “Mighty Moose” appear to be really powerful tool that tracks both code and tests changes, and in case of changes taking place it automatically re-runs all related test cases. So, we’ve grabbed the latest version on MM and played with it a bit. MM is officially in betta now and gonna to be release soon, so did a small contribution by submitting some bugs found on a fly. I also really much enjoyed the quick demonstration of Simple.Testing framework. It worth to have a separate blog post on that, but in short - it is BDD style framework that literally produce plain English specifications as it’s output. It’s indeed very simple - just several hundreds LOC’s, but very impressive.

But of cause, the main event was Free Event Centric Weekend. It is very hard to describe what was there just in this short post. You might check out some tweets on #eventcentric channel. Greg and Rinat were sharing their huge experience on CQRS/DDD and I would say that was extremely interesting. I’m not using either CQRS or DDD on my daily work, so a lot of new concept’s I’ve heard are still really unknown to me, but I’m happy I looked behind the curtain. Greg is Ri level developer - he is simply breaking the concepts. Seriously, I was blown away with some of the statements and my brain is still “damaged” with everything I heard there.


Eventcentric meeting in Kyiv

Besides of that we had several cool evenings, drinking beers. I would say that was great week and I’m really happy to meet you guys. I would also say big thanks to KievAltNet, Luxoft with support they provided to make this happen. I know this in not your last visit to Kiev, so see you soon!

ps. As more you know as more unknown you are able to see…

NETWork Conference in Kharkiv

In short, it was one of the most exciting and interesting conferences I ever been (and participated) so far. My big respect goes to organizers: Sigma Ukraine, Akvelon and Ciklum as main sponsor.

In a little long, I’ve been invited to participate this conference by Anastasia Kladova, the PR manager of Sigma Ukraine during my visit of IT Jam 2011 this summer. It sounded so cool to me, since so famous guys as Ayende, Greg Young and Rinat Abdulin would be the speakers there as well. I had not other choice, just to agree.

Well, my trip to Kharkiv started not very good. Due to my personal awkwardness I simply missed the train. Now I have fun of that fact, by then I was standing on station and seeing my train passing away - it was not so fun to me. Anyway, with great advice of @chaliy by phone I switched to another train. The one one problem was - it comes to Kharkiv pretty late, at 10.00 o’clock.

Unfortunately I missed first keynote by Sander and first session of speeches. But I was ready for the rest of the day. I would not describe long my feelings to meet colleagues from other cities, which we communicate thought twitter. But it is exactly the conferences like that, where we have real opportunity to talk to each other. As for me, such communication is a bigger asset of any conference including NETWork.




Let me share some feedback I got about the speeches I visited:


  • CQRS AND EVENT SOURCING by Greg Young - I really much enjoyed the that speech. Doesn’t matter I’ve seen it before on video :) - still I was amazed about his speakers skill and energy he exposed towards the audience. His mimic, body language and personal behavior - made the speech really attractive. I would not say I heard something really new to me, but at least I improved some knowledge I already had.

  • APPLIED CODE GENERATION IN .NET by Dmitry Mindra - great talk about Code Generation in .NET application. Even, if I dislike code generation much, Dmitry managed to find good Pros. and Cons. of code generation. So, at the end of the speech I even was not possible to start holy war on that topic, since really strong facts he had.

  • INSIDE ASP.NET MVC FRAMEWORK be me - yeah, that’s my speech so I’m not really happy as usual. Again, I didn’t fit everything I wanted to say. Something that I did seems was not really clear and far away from comprehensive. It would be last attempt I do that ‘Inside MVC’ talk - it is simply too big, so probably next time I just select one small topic and focus on that. Anyway, I all the time enjoy the speaking and I really like that feeling of stress before and relax after :).

  • NOSQL – A CHANGE OF PERSPECTIVE FOR THE DEVELOPER OF TODAY by Ayende - I have a split decision on that. The beginning of the speech was simply boring, I don’t understand the reason of spending 0.5h do describe the difference of price of 1 Mb HDD in 80’s and 00’s. Moreover, due to Ayende’s accent sometimes I just missed the idea. The end of the speech were more exiting but still I was disappointed. Ayende is great developer, everybody knows that - but it was not even one small example of code working with RavenDB. Probably he left it for some practical session, but still I think it is kind of drawback of his presentation.

And after all speeches we had a kind of Round Table. All speaker got on stage and answering the questions of audience. It was a little funny to me how it went. First, the language - some questions were in English but answered in Russian, some was Russian but answered English :). I actually used English in respect towards our foreign guests, but anyway. The answers were long, not exact and mainly loosing the point of original question. I think the moderation (with a timing and topics) is really important here.

What I remembered the most is the question to Ayende - “How you became so productive?”, and the answer was something that great developer should answer “I’m not so productive, I just code a lot and do some blog posts”. Yeah, “Code a lot” - so simple rule to became from good to great. I’ll remember that.

Finally we had a great dinner at the one of Kharkiv’s restaurant’s. And I went to train station (0.5 hours ahead). There I met my guys from Kiev ALT.NET who had a great mood and bag full of beer. So, we’ve had nice Beer && Talk session till 3.00 AM on our way back home.

Inside ASP.NET MVC: IDependencyResolver - Service locator in MVC

All types inside ASP.NET MVC3 framework are being resolved by IDependencyResolver. The design goal of this interface is to provide flexibility and decrease coupling between components.

namespace System.Web.Mvc {
    using System.Collections.Generic;

    public interface IDependencyResolver {
        object GetService(Type serviceType);
        IEnumerable<object> GetServices(Type serviceType);
    }
}

If take a look into the code you will definitely smell the Service Locator pattern. Indeed, IDependencyResolver is pure service locator.

DependencyResolver as IDependencyResolver holder

IDependencyResolver instance is being accessed through the DependencyResolver class.

public class DependencyResolver {
 // Static accessors

 private static DependencyResolver _instance = new DependencyResolver();

 public static IDependencyResolver Current {
  get {
   return _instance.InnerCurrent;
  }
 }

It is a singleton class, current instance is being accessed through Current property. The default implementation is DefaultDependencyResolver.

// Instance implementation (for testing purposes)

private IDependencyResolver _current = new DefaultDependencyResolver();

Even if the comment says (for testing purposes) that class is used in real code. Let’s take a look on that.

private class DefaultDependencyResolver : IDependencyResolver {
 [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
 public object GetService(Type serviceType) {
  try {
   return Activator.CreateInstance(serviceType);
  }
  catch {
   return null;
  }
 }

 public IEnumerable<object> GetServices(Type serviceType) {
  return Enumerable.Empty<object>();
 }
}

As you might see, it is extremely simple. It just tries to resolve the type by Activator class. If the type could be resolved it just returns it’s instance, otherwise just return null. The GetServices method just returns empty enumerable.

Substituting default DependencyResolver

As I said above, the main design goal of DependencyResolver is to provide flexibility. By flexibility I mean just easy way to substitute any type with own implementation. Say you want to change the ControllerFactory or ModelBinder or what ever you like. Everything is possible just by overriding IDependencyResolver.

I’ve seen one common misconception about MVC3, that it is contains IoC container inside it. It is not true, but it expose the interface which really much suites interfaces of famous IoC containers. To do not have a strict rules and force developers to use one type of IoC, ASP.NET MVC developers created a facility by which you can integrate yours IoC of choice. Let’s have a look how to do that.

DependencyResolver contains the number of setters to substitute the instance.

public static void SetResolver(IDependencyResolver resolver) {
 _instance.InnerSetResolver(resolver);
}

public static void SetResolver(object commonServiceLocator) {
 _instance.InnerSetResolver(commonServiceLocator);
}

[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types.")]
public static void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
 _instance.InnerSetResolver(getService, getServices);
}

As example of implementation here my very dummy dependency resolver.

namespace MvcForDebug2.Infrastructure {
    public class DummyDependencyResolver : IDependencyResolver {
        public object GetService(Type serviceType) {
            if (serviceType.Equals(typeof(IControllerFactory))) {
                return new DummyControllerFactory();
            }

            return null;
        }

        public IEnumerable<object> GetServices(Type serviceType) {
            return null;
        }
    }
}

Finally, in global.asx.cs you need to set it up.

protected void Application_Start()
{
 AreaRegistration.RegisterAllAreas();

 RegisterGlobalFilters(GlobalFilters.Filters);
 RegisterRoutes(RouteTable.Routes);

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

Conclusions

IDependencyResolver is a powerful feature of ASP.NET MVC3. It is used to create all internal MVC types, so by overriding it you can override default behavior of many framework aspects. Typically you should not have any complex code in GetService and GetServices methods, but instead just delegation of call to IoC container.

The Power of Close Collaboration

The collaboration and communication is very important in solving problems. As much better collaboration you have as much fast you are able to handle different issue. As closer people to each other, as better they able to work. That’s why I think that distributed teams even if they consists of great engineers could not work 100% of their potential. Lags in communications, language barrier, loose of body languages etc. makes it 80% for best cases.

As you might know I’m currently working on candidate.net project. I really want to release that and according to my original plans I was really close to do that. But, suddenly my application just stopped to work. I’ll skip details of bug, but it was a ship killer. Application was not able to clone/pull github repositories. The only thing that happened between periods of working and non-working states is that I upgraded my Windows 7 up to SP1.

Even if I had great support by @ukraitor who forked my project recently, we were not able to solve it (remember, distributed teams - he is from Odessa, far from me). I was pulling out my hair and mostly lost a hope to solve that. But I decided to share the problem on latest Beer && Code meeting we had this Tuesday.

It is usually hard to explain your problem. Along the process, I think to myself - “those people are pretty far from problem context, could they indeed help me?”. The simple answer is “Yes, they can”. Never underestimate the people around you.

During 2 hours we’ve been able to try different scenarios, discuss some potential issues and finally found a clue! I was so happy about that, at least my work moved from a dead point. I’m sure, I could not complete it by my own (in reasonable time).

So, my point is: if you are in work project - immediately share you problem with colleagues don’t make yourself completely stucked. If you work on your own project - it is better if you find a collaborator, if you don’t have one you might find a local group, like Beer && Code or talk to your developers friends whatever.

Remember, as closer the collaborator is as better. Special thank’s today goes to @chaliy who helped to solve the issue.

Branching Workflow in Git-SVN Mode

As you might already know branches are primary power of Git. You should create branch for every task you working on. Even if it is something small you easily starting to get a good habit of creating branches, since they keep you much in isolation. So, how to deal with branches in Git-SVN mode? It is really easy and conforms to common git practices.

So, as you cloned the SVN repo you have master branch (or several masters, if you did more switches). Suppose you need to start to work on ticket ND-177.

  1. Create new branch for ND-177 (I call new branch like, original_branch-branch_name)
  2. git checkout -b master-nd-177   
    
  3. Do your work here, performing as many commits as you need
  4. get commit -a -m "some intermediate commit.."
    
  5. Now, as you are ready to be merged you to SVN, you checkout and rebase master (to get latest SVN changes from it)
  6. git checkout master
        git svn rebase
    
  7. You can simply merge 2 branches, but with simple merge you will get all commits history that you probably don’t need in SVN at all. You squash to compress number of commits into one nice looking commit object
  8. git merge --squash master-nd-177
    
  9. It would merge up all changes from master-nd-177 into master. All you need to do is commit
  10. git commit -m "ND-177 completed"
    
  11. And dcommit changes to SVN server
  12. git svn dcommit
    

That’s six basic steps makes really straightforward workflow for everyday usage.

What I’m Going To Do

Lazy summer days have gone and cool September came. It is good time to think, decide on projects and goals. No time to chill.

I have a different things in my mind, all the time. My biggest problem is loosing focus and task switching. I simply can not do one thing for quite long time. I need something new, I need to satisfy my exploration instinct. In the same time, achievement of results require much focus. I would like to be more focused.

I’ll try to formulate my current projects and expectations I have. That’s my active projects, sorted by priority:

  • economic.com - my job. Working for economic is very important to me since it is main project that gives me money. We are doing interesting things there, problem is our technological stack and frameworks are outdated. That’s typical stage for every big project and pretty de-motivator for developers (especially me). Working with old stuff is hard and boring, that’s fact. But we have good team there and hope we are able to solve problems and move to bright future.
  • candidate.net - the application I started on Kiev Hackatone. Remember I was describing my experience with Continues Delivery based on Jenkins? That worked and works for me perfectly, expect the fact that Jenkins is Java application and consumes a lot of recourses (but I have quite limited resources on my VSP, actually). Candidate is the one who going to substitute Jenkins for me. Based on a power of Bounce and Roundhouse I will create nice and easy to use Continues Delivery tool for .NET websites and of cause release it open sourced for everyone. BTW, Candidate is working name and I’m looking for cool name for it, if you have any ideas let me know.
  • trackyt.net - the first application I build and released on my own. Exactly this project gave me knowledge of “release” and how tough and hard it is. I haven’t write about it and haven’t done any major release recently. My bad. I’m not going to close that project. Still they say me “there are 1.000.000 GTD application around the internet”, you know - I don’t care. 10 month passed after version 1.0 released and it is only now I really understand what I want to create. I’ve been user of trackyt by myself for long time, I’ve collected priceless feedback of my friends.. I gathered more experience in building that kind of applications. I have clear vision both application and technology stack I’m going to use. I’m not happy with current version (and project name), so I’m simply going to start from scratch. Release 2.0 will be much interesting and useful, at least I hope that much.
  • beletsky.net - my blog. Least but not last, since beletsky.net is my biggest motivator. I will continue my Inside ASP.NET MVC as well as all other things I try to put here. Of cause, producing good content is very difficult job.. but you are (readers) could improve it much. Don’t be lazy to post comments and any other feedback. It is really important for every blogger.

Besides of that I’m really happy that this year I joined Kiev ALT.NET community. Recently we also started to have Beer-n-code sessions, that is really cool. I’m going to continue my contribution there as well.

ELMAH MVC controller released on NuGet

I dedicated some time for that and happy to announce - ELMAH MVC controller released on NuGet.

Due to the latest interest, feedback and changes - it has no sense at all to keep that code just in blog post. In my previous post I promised to create NuGet package for that, so here we are:

PM> Install-Package Elmah.MVC

I simplified code even a little more to avoid changing in routes (in case of Admin area already exists in project).

So just grab it from NuGet now.