• Sunday, January 15th, 2012
On-the-fly building on where clauses of query statements to
fire against a data store is a common problem in most of the applications. Linq
is a concept of querying data a first class programming concept in .NET, and
enables you to efficiently express queries in your programming language of
choice. Linq allows you to write type-safe queries, most of the times you need
to construct queries on the fly based on some filter conditions.
The Dynamic query library provided by Microsoft helps you to
construct linq queries by passing a string value for where condition or an
expression that can be evaluated at runtime. In this post we’ll see how to
construct expressions for the where clause dynamically using a combination of
builder and specification pattern.
Creating a class for filter options
public class UsersFilterOption
{
public string Name { get; set; }
public string Country
{ get; set; }
public string Role { get; set; }
public string Email {
get; set; }
public string
Telephone { get; set;
}
}
The condition builder class is used to add expressions as specifications to the Specification based on the filter options.
public class UserWhereConditionExpressionBuilder
{
private readonly UsersFilterOption _filterOptions;
private Specification<User> _result = new
TrueSpecification<User>();
public UserWhereConditionExpressionBuilder(UsersFilterOption usersFilterOptions)
{

_filterOptions = usersFilterOptions;
}
public UserWhereConditionExpressionBuilder
Name()
{
var shouldBuild = !string.IsNullOrEmpty(_filterOptions.Name);
if (!shouldBuild) return
this;

_result &= new DirectSpecification<User>(u
=> u.Name.ToUpper().Contains(_filterOptions.Name.ToUpper()));
return this;
}
public UserWhereConditionExpressionBuilder
Email()
{
var shouldBuild = !string.IsNullOrEmpty(_filterOptions.Email);
if (!shouldBuild) return
this;

_result &= new DirectSpecification<User>(u
=> u.Email.ToUpper().Contains(_filterOptions.Email.ToUpper()));
return this;
}
public UserWhereConditionExpressionBuilder
Country()
{
var shouldBuild = !string.IsNullOrEmpty(_filterOptions.Country)
&&
System.String.CompareOrdinal(_filterOptions.Country, “ALL”) != 0;
if (!shouldBuild) return
this;

_result &= new DirectSpecification<User>(u
=> System.String.Compare(u.Country,
_filterOptions.Country, System.StringComparison.OrdinalIgnoreCase)
== 0);
return this;
}
public UserWhereConditionExpressionBuilder
Role()
{
var shouldBuild = !string.IsNullOrEmpty(_filterOptions.Role)
&&
System.String.CompareOrdinal(_filterOptions.Role, “ALL”) != 0;
if (!shouldBuild) return
this;

_result &= new DirectSpecification<User>(u
=> System.String.Compare(u.Role,
_filterOptions.Role, System.StringComparison.OrdinalIgnoreCase)
== 0);
return this;
}
public Specification<User> GetWhereCondition()
{
return _result;
}
}
The construct method on the builder class constructs the expression from the condition builder class. I’ve implemented the condition builder class as fluent interfaces for easy use.
public class UsersWhereCondition
{
public static ISpecification<User>
Construct(UsersFilterOption filterOptions)
{
var builder = new UserWhereConditionExpressionBuilder(filterOptions);
return

builder

.Name()

.Email()

.Country()

.Role()

.GetWhereCondition();
}
}
Using these classes you can construct the query condition for
the dynamic linq clause as given below
var whereCondition = UsersWhereCondition.Construct(filterOptions);

var data = from user in userFactory.GetAll()

.Where(whereCondition.SatisfiedBy());
Author: nagendra
• Thursday, December 22nd, 2011

Before starting with how to achieve continuous integration with TFS, lets try and understand why it is required?

Wiki says:

In software engineering, continuous integration (CI) implements continuous processes of applying quality control — small pieces of effort, applied frequently. Continuous integration aims to improve the quality of software, and to reduce the time taken to deliver it, by replacing the traditional practice of applying quality control after completing all development.

Which is very true!

And the principles of continuous integration are :

  1. Maintain a code repository
  2. Automate the build
  3. Make the build self-testing
  4. Everyone commits to the baseline every day
  5. Every commit (to baseline) should be built
  6. Keep the build fast
  7. Test in a clone of the production environment
  8. Make it easy to get the latest deliverables
  9. Everyone can see the results of the latest build
  10. Automate deployment

If you can think for a while how every stuff adds value and helps in getting the quality product out at a higher rate by reducing risk you have already 50% through with the process. Rest all is matter of utilizing the feature provided by the CI tools/infrastructure.

Lemme start with maintaining code repository. If you follow few guidelines, it makes the life much easier to maintain the code. It all depends on nature of the application & process you follow.

Define your environments:

Defining branching is major decision to be taken and it all depends on the scenario or the process you are in. Go throw this site before strategizing the branchinghttp://branchingguidance.codeplex.com/.

For instance, lets consider a simple branching strategy around environments (dev,qa & prod) with single release.

Define environment dependant configuration:

First and foremost, define the configurations for each environment. Configurations as such, DB to point, service url to refer, user accouts to be used etc. This can be achived by having a configuration file each environment.

1.       Select the solution

2.       Right cick -> configuration manager

3.       Define the configuration for all environments (and debug/release modes for local settings & dev workarounds) -> Using Configuration Manager

4.       Make use of the interesting feature Add Config Transforms offerred by VS2010/.net4.0 web application project template to maintain web.config for each configurations.

5.       Strangly we don’t have this luxury for other application templates. Thr is a combursome procedure of modifying your cs proj file to achive this feature (refer:http://philbolduc.blogspot.com/2010/03/using-config-transforms-outside-web.html).

I prefer to write a small batch scripts which overrides the app.config  befroe the build. Call the batch script on pre-build event of the project.

Define TFS build for each environment:

TFS2010 has very strong and extensible support for build J. Its easy and scallable. You can get a smiple build procedure up, by following the new build wizard

1.       Go to team explorer in VS 2010 ->  Builds -> New Build Definition

2.       Define the build for dev environment.

a.       Name

b.      What triggers the build. Notice the interesting scheduling options J

c.       For which solution?

Path of the soultion to build. You can have multiple solutions build on same time. Have an eye on Build Agent Folder path.

d.      Need to drop the output of the build to a location? Oh yeah, you can do it in build defaults.

e.      Here comes the most important step of build definition, the Process.

f.        Quick tips:

i.      As I stated earlier, we will be having a different builds for each environment. Now it’s the time for chosingthe configuuration we defined. Provide appropriate configuration name for the property Configuration to  Build.

ii.      Want to run the unit testcases? Provide the assemblies for the propert “Test Assembly Filesspec”.

iii.      Want to fail the entire build on test fail even if the compliation was successful ? set “Fail Build On Test Failure” to true

iv.      Want to run the code coverage? Enable code coverage (refer): http://blogs.msdn.com/b/ukvsts/archive/2009/11/06/enabling-code-coverage-in-vs-2010-beta-2.aspx) and provide the local.testsettigns file to “TestSettingsFile”.

v.      Want to run the Code Analysis on the build? Set the “Perform Code Analysis” option. Make sure, you have selected appropriate rulesets in the project (refer:http://visualstudiomagazine.com/articles/2010/03/25/working-with-static-code-analysis.aspx).

vi.      Want to deploy the application? (Only Web Apps) Provide publish parameters to “MSBuild Arguments

/p:DeployOnBuild=True

/p:DeployTarget=MsDeployPublish

/p:MSDeployPublishMethod=InProc

/p:CreatePackageOnPublish=True

/p:DeployIisAppPath=”Default Web Site/WebApplication1″

/p:MsDeployServiceUrl=localhost

Ref: http://weblogs.asp.net/jdanforth/archive/2010/04/24/package-and-publish-web-sites-with-tfs-2010-build-server.aspx

vii.      How to deploy web or any other applications? This is a generic process, invbolves writign some batch scripts J

Ref : http://blogs.msdn.com/b/benoitsarie/archive/2010/06/03/how-to-deploy-a-web-application-with-web-application-project-deployment-part3.aspx

g.       You define the rention policy too.

This ends defining the build for a specific environment. Repeate the above steps for other 2 environments/branches with environment specific details such as ,

1.       Solution location

2.       Scheduling

3.       Drop location

4.       Configuration to run

5.       Enablingor disabling of Automatic deployment, Runnign unit test, code coverage or any other details.

Once we have have all the 3 build definitions defined, we can view, enquue,delete or modify the build.

Click onView Builds to see all possible builds

Click Open to explore  different features provided and majorly to see what happened with the build.

Opt for alerts to be on track with build status by selecting Project alert option under “Team” menu in toolbar.

Author: nagendra
• Tuesday, December 20th, 2011

I was told to write blogs many times in many ways! I always wanted to write a blog too. And I did write few on an average of one blog/year. I was never motivated to write blogs. But then, one day I had really interesting conversation with couple folks at my work place. Even that did not motivate me to write a blog, but that conversation made me ask myself lot many question about writing blog.

The answer I got back was, It was not about writing blog. It’s more about telling a story, sharing an experience and I read somewhere “if you don’t tell your story then who will?” I think, that makes a lot of sense! Ironically, I got that from a blog!

So, I decided to write this blog to talk about why to write a blog or tweet.

I know, most of us are fascinated by history. It amazes surprises and even horrifies us.  What is the biggest take from history the current generation is enjoying? “The lessons learnt”. So, how did we receive all these information? Was these things told to us by our ancestors? How? As stories? How did they communicate their experiences to us? Who told us?

What would have happened, if everybody has seized their knowledge to themself? Lemme not elaborate too much, you know what I’m talking about!

You have learnt something from the community you are in. It’s your responsibility to give it back! We living in the digital world should be very lucky that we can contribute back without much effort. And that need a not be a blog!

Communication is important. How do you communicate effectively is even more important. The best way of communication is make use of the digital world u live in. It is fine, if you write a book! It’s fine, if you click a pic! Don’t miss to tell the story! Whatever it might be, something which has a flavor is always stands out! You story has a flavor, share it! Just, casually share your thoughts “If you don’t tell your story then who will?”

Category: General  | Leave a Comment
Author: Anand
• Friday, December 16th, 2011

If you want to restrict access to your Azure webrole (url) based on users’ IP Address, then this is the best article:

http://blog.bareweb.eu/2011/04/restricting-access-by-ip-in-azure-web-role-v1-4/

It has clear instructions and screenshots. But if your webrole keeps restarting when trying out those instructions, then read further for a fix.

However, I just couldnt get it working at first. When I added the “Startup.cmd” to my project as mentioned in the article and tried to publish, the it just wouldnt publish. It would just show me publish in progress for a long long time. On the Azure Management Portal, the webrole would just keep restarting.

I had to connect to the webrole using remote desktop to figure out the issue. (Ref: http://msdn.microsoft.com/en-us/library/windowsazure/gg443832.aspx)

It turns out, I needed to save the “Startup.cmd” file as an “ANSI” text file and NOT Unicode as mentioned in that article.

So they you go, just save the file in a different text format and things should work for you as described in that article.

- Anand

• Friday, December 09th, 2011
Interceptor pattern can be used for addressing cross cutting
concerns in the application that happens at either the beginning or end of a
method. For e.g. checking the validity of the input parameters before executing
the method and throwing exceptions, catching and logging exceptions etc. These
situations can be encapsulated in a reusable component that can be processed by
the compiler and produce executable code (AOP).
Unity allows developers to implement the idea of
interception by allowing creation of objects that can add some extra code on
the target method before or after the regular execution of these target
methods. In this post, I’ll show how to create a Session handler for ASP.Net
using the interface interception mechanism provided by unity application block,
that will allow you to address encapsulate the logic for checking session for a
value before execution of the method and returning back the value from session
if available. The same handler can be used to also add the return value to the
session if not available so that this value can be retrieved next time.
Creating the session handler
public class SessionHandler : ICallHandler
{
private readonly string _sessionKey;
public SessionHandler(string
sessionKey)
{

_sessionKey = sessionKey;
}
public ISessionService
SessionService
{
get { return Container.Instance.Resolve<ISessionService>(); }
}
public IMethodReturn
Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
if (SessionService.Contains(_sessionKey))
{

input.CreateMethodReturn(SessionService.Get(_sessionKey));
return getNext()(input, getNext);
}
var returnValue = getNext()(input, getNext);
SessionService.Add(_sessionKey,
returnValue.ReturnValue);
return returnValue;
}
public int Order { get; set; }
}
The session handler uses the session service which
encapsulates the actual Session object to add/ remove values from the
session.  You can also use the
HttpContext.Current.Session object here.
Creating the Attribute for the handler
public class SessionDependencyAttribute : HandlerAttribute
{
private readonly string _sessionKey;
public SessionDependencyAttribute(string sessionKey)
{

_sessionKey = sessionKey;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new SessionHandler(_sessionKey);
}
}
Creating a service and using the SessionHandler we created.
public interface IMockService
{
[SessionDependency("TestKey")]
string GetValue(bool
flag);
}
public class MockService : IMockService
{
public string
GetValue(bool flag)
{
return flag ? “True”
: “False”;
}
}
Configuring the Unity container
_container = new UnityContainer();
_container.AddNewExtension<Interception>();
_container

.RegisterType<ISessionService, SessionService>()

.RegisterType<IMockService, MockService>()

.RegisterType<MockPresenter>()
.Configure<Interception>().SetDefaultInterceptorFor<IMockService>(new
InterfaceInterceptor());
Test cases
[TestMethod]
public void
MethodShouldReturnValueFromSessionIfValueDoesNotExistsAndAddToSession()
{
var service = Container.Instance.Resolve<IMockService>();
var actual = service.GetValue(true);
Assert.IsTrue(SessionService.Contains(“TestKey”));
}
• Monday, November 28th, 2011

Unity is a lightweight, extensible dependency injection

container with support for nested containers that stores registrations and
mappings between types and can instantiate the appropriate concrete types on
demand. Identification of the registrations in unity can be done using a type
and a name (optional).
You can use unity to register multiple implementations of
the same type and later resolve the actual instance by passing the name for
identifying the actual implementation. In this post we’ll see how to resolve
the instances registered in unity application block conditionally.
For e.g. I have created a sample interface and
implementations as given below
public interface IMyObject
{
string DoSomething();
}
public class MyObjectFirstImplementation : IMyObject
{
public string
DoSomething()
{
return “First”;
}
}
public class MyObjectSecondImplementation : IMyObject
{
public string
DoSomething()
{
return “Second”;
}
}
The registration of these components are done like
container

.RegisterType<IMyObject, MyObjectFirstImplementation>(DependencyRegistrationKeys.FirstImplementation)

.RegisterType<IMyObject, MyObjectSecondImplementation>(DependencyRegistrationKeys.SecondImplementation);
public static class DependencyRegistrationKeys
{
public const string FirstImplementation = “FIRST_IMPLEMENTATION”;
public const string SecondImplementation = “SECOND_IMPLEMENTATION”;
}
The factory class has a create method that accepts and
object key to resolve the actual instances
public class MyObjectFactory
{
public IMyObject
Create(string objectKey)
{
return Container.Instance.Resolve<IMyObject>(objectKey);
}
}
Tests
[TestMethod]
public void
CreateMethodShouldReturnTheObjectImplementationBasedOnConditionPassed()
{
var factory = new MyObjectFactory();
var myObject = factory.Create(DependencyRegistrationKeys.FirstImplementation);
Assert.IsInstanceOfType(myObject, typeof(MyObjectFirstImplementation));
}
• Monday, November 21st, 2011
In this post I’m going to create a generic implementation of
the specification pattern.
The central idea of Specification is to separate the
statement of how to match a candidate, from the candidate object that it is
matched against. As well as its usefulness in selection, it is also valuable
forvalidation and for building to order. Every specification implementation
needs to specify a method that evaluates a condition mentioned in the interface
Ispecification as given below.
public interface ISpecification where
T : class
{
Expression<Funcbool>> SatisfiedBy();
}
The generic specification class implements the Ispecification
interface as
public sealed class Specification
: ISpecification where T : class
{
readonly Expression<Funcbool>>
_matchingCriteria;
public Specification(Expression<Funcbool>>
matchingCriteria)
{
if (matchingCriteria == null)
throw new ArgumentNullException(“matchingCriteria”);

_matchingCriteria = matchingCriteria;
}
public Expression<Funcbool>>
SatisfiedBy()
{
return _matchingCriteria;
}
}
Using this implementation we can create the AND
specification as
public sealed class AndSpecification
: ISpecification where T : class
{
private readonly ISpecification _rightSideSpecification;
private readonly ISpecification _leftSideSpecification;
public AndSpecification(ISpecification
leftSide, ISpecification rightSide)
{
if (leftSide == null)
throw new ArgumentNullException(“leftSide”);
if (rightSide == null)
throw new ArgumentNullException(“rightSide”);

_leftSideSpecification = leftSide;

_rightSideSpecification = rightSide;
}
public ISpecification
LeftSideSpecification
{
get { return
_leftSideSpecification; }
}
public ISpecification
RightSideSpecification
{
get { return
_rightSideSpecification; }
}
public Expression<Funcbool>>
SatisfiedBy()
{
var left = _leftSideSpecification.SatisfiedBy();
var right = _rightSideSpecification.SatisfiedBy();
return (left.And(right));
}
}
The AND method is an extension method on the ISpecification and
Expression<Funcbool>>
types
public static ISpecification AND(this ISpecification
leftSpecification, ISpecification
rightSpecification) where T : class
{
return new AndSpecification(leftSpecification,
rightSpecification);
}
public static Expression Compose(this Expression
first, Expression second,
Func<Expression,
Expression, Expression>
merge)
{
var map =

first.Parameters.Select((f, i) => new
{f, s = second.Parameters[i]}).ToDictionary(p => p.s, p => p.f);
var secondBody = ExpressionTreeParameterReplacer.ReplaceParameters(map,
second.Body);
return Expression.Lambda(merge(first.Body,
secondBody), first.Parameters);
}
public static Expression<Funcbool>> AND(this Expression<Funcbool>>
first,

Expression<Funcbool
>> second)
{
return first.Compose(second, Expression.And);
}
The ExpressionTreeVisitor implementation to replace and join
the parameters for these extension methods
public sealed class ExpressionTreeParameterReplacer
: ExpressionVisitor
{
private readonly Dictionary<ParameterExpression,
ParameterExpression> _map;
public ExpressionTreeParameterReplacer(Dictionary<ParameterExpression,
ParameterExpression> map)
{
_map
= map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
public static Expression ReplaceParameters(Dictionary<ParameterExpression,
ParameterExpression> map,

Expression exp)
{
return new ExpressionTreeParameterReplacer(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression
p)
{
ParameterExpression replacement;
if (_map.TryGetValue(p, out
replacement))
p
= replacement;
return base.VisitParameter(p);
}
}
Now let’s look at a sample using the specification pattern
implementation.
public class Customer
{
public string
FirstName { get; set;
}
public string
LastName { get; set;
}
public string
UserName { get; set;
}
public DateTime
DateOfJoining { get; set;
}
public Address
Address { get; set;
}
}
public class Address
{
public string Street
{ get; set; }
public string State {
get; set; }
public string City { get; set; }
public string Country
{ get; set; }
}
public class CountryNameSpecification : ISpecification<Customer>
{
private readonly string _countryName;
public CountryNameSpecification(string countryName)
{

_countryName = countryName;
}
public Expression<Func<Customer,
bool>> SatisfiedBy()
{
return new Specification<Customer>(c
=> c.Address.Country.Contains(_countryName)).SatisfiedBy();
}
}
public class CustomerFirstNameSpecification :ISpecification<Customer>
{
private readonly string _firstName;
public
CustomerFirstNameSpecification(string
firstName)
{

_firstName = firstName;
}
public Expression<Func<Customer,
bool>> SatisfiedBy()
{
return new Specification<Customer>(c
=> c.FirstName.Equals(_firstName)).SatisfiedBy();
}
}
[TestMethod]
public void
AndSpecificationShouldSatisfyIfBothExpressionsSatisfiesTheCondition()
{
var customers = GetAllCustomers();
var fooCountrySpecification = new CountryNameSpecification(“Foo”);
var customerFirtNameSpecification = new CustomerFirstNameSpecification(“Foo4″);
var andSpecification =
fooCountrySpecification.AND(customerFirtNameSpecification);
var results =
customers.Where(andSpecification.SatisfiedBy());
Assert.IsTrue(results.ToList().All(c =>
c.Address.Country.Contains(“Foo”)
&& c.FirstName.Equals(“Foo4″)));
}
[TestMethod]
public void
OrSpecificationShouldSatisfyIfOnOfTheConditionsSatisfiesTheSet()
{
var customers = GetAllCustomers();
var fooCountrySpecification = new CountryNameSpecification(“Foo”);
var abcCountrySpecification = new CountryNameSpecification(“Abc”);
var pqrCountrySpecification = new CountryNameSpecification(“Pqr”);
var orSpecification =
fooCountrySpecification.OR(abcCountrySpecification).OR(pqrCountrySpecification);
var results =
customers.Where(orSpecification.SatisfiedBy());
Assert.IsTrue(results.Count() ==
customers.Count());
}
Where GetAllCustomers return an Iqueryable resultset of
customers with addresses.
• Wednesday, September 14th, 2011
Of all the Lean Startup techniques, Continuous Deployment is by far the most controversial. Continuous Deployment is a process by which software is released several times throughout the day – in minutes versus days, weeks, or months. Continuous Flow Manufacturing is a Lean technique that boosts productivity by rearranging manufacturing processes so products are built end-to-end, one at a time (using singe-piece flow), versus the more prevalent batch and queue approach.
Continuous Deployment is Continuous Flow applied to software. The goal of both is to eliminate waste. The biggest waste in manufacturing is created from having to transport products from one place to another. The biggest waste in software is created from waiting for software as it moves from one state to another: Waiting to code, waiting to test, waiting to deploy. Reducing or eliminating these waits leads to faster iterations which is the key to success.” – Eric Ries
Continuous deployment is one of the new trends in agile development that ensures release of software in a faster and reliable manner. It also helps the team to deliver value to customers early and often. In this post I’ll show how to setup a continuous integration environment using TeamCity and MSBuild scripts created by using a Web deployment project deploy your website every time a check in happens into the source safe.
TeamCity is a user-friendly continuous integration (CI) server from jet brains that is available as a free download from the vendor website. You can use go to the website http://www.jetbrains.com/teamcity/ to get your free copy. I have also used the Web deployment project from MS for MSBuild script generations in this sample.
For setting up the automated deployment on a website, you can follow the below given steps.
  • Right click on the web application project for automated build and select Add Web Deployment Project
  • On the ‘Add Web Deployment Project’ dialog give an appropriate name for the deployment project and press OK. This web deployment project created for the web application is the build scripts for MSBUILD.
  • Next we can create the build configuration setup for the project. For this right click the solution and select Configuration manager.
  • Unselect the build option for ‘Debug’ and ‘Release’ configurations for the Deployment project.
  • On the Active solution configuration drop down select ‘New’
  • On the ‘New Solution Configuration’ dialog, enter the name for the deployment configuration and press OK. Close the configuration manager window by selecting Close.
  • Next we’ll create separate configuration options for staging environment. For e.g. the connection strings for the staging server will be different that the development environment. Right click the web application and add a new folder ‘Configuration’
  • In the Configuration folder add a new configuration file ‘ConnectionStrings.Staging.Config’ and include the connection strings for the staging environment in this file. These settings will be replaced with the connection strings section in the web.config file when the deployment is started.
  • We’ll now setup the deployment properties for the project. For that, right click the deployment project and select property pages.
  • Change the output folder to the location where the build output will be deployed to.
  • On the deployment section of the property pages, you can set transformations on the configuration options for the application. You can also mention the virtual directory options on this page. Save the settings by selecting OK.
  • Next we have to configure the project on Team city. Login to team city as administrator and navigate to the Administration tab. On the administration page, select ‘Create Project’. Give an appropriate name for the project and select ‘Create’ option on the page.
  • Next we have to configure the VSC settings used by TeamCity to obtain the source files for the build. For this select the VCS roots tab and click on ‘Create VCS roots’.
  • Select the type of source control from the ‘Type of VCS’ dropdown to enter the source control specific configuration entries. Enter the URL, username, password and other details for the sub version and click on Create to update the configuration information.
  • On the general tab, select ‘Create new build configuration’ to enter details for the build configuration. Enter a name for the build configuration and select VCS settings to continue.
  • On the next page enter details for the checkout directory and Select ‘Add build Step’.
  • Select MSBuild as the build runner and enter the name of solution as the Build file path option.
  • On the build triggering, select ‘Add new trigger’. And select VCS trigger to trigger the build on every check in done to the source safe.
  • Select Save and you have successfully created an automated build setup for your web application.
• Thursday, August 11th, 2011
ASP.NET was not designed with the concepts of DI and IoC in mind. That makes it very difficult to actually configure a website/ application using ASP.NET to use the concepts of IoC and resolve the dependencies when the pages are requested. An easier way to resolve the dependencies on the page will be using the container and requesting for the resolved types for dependencies. A much better approach is to interpret the page creation implementation code in ASP.NET and resolve the dependencies on the Page from there. In this post I’ll show a sample scenario where we’ll intercept the page creation logic and resolve the dependencies on the page using Unity container.
The sample used in this article has views that have dependencies on the respective presenters. The presenters will depend on the service abstractions to do their work.
I have the base presenter and view interface declarations as
public abstract class AppPresenter where T : IAppView
{
public T View
{
get
{
if (HttpContext.Current == null) return DependencyInjection.Container.Resolve();
return (T)HttpContext.Current.Handler;
}
}
public abstract void InitializeViewEvents();
}
public interface IAppView
{
}
For resolving the dependencies on my views, I have created a custom PageHandler implementation which looks like.
public class UnityPageHandlerFactory : PageHandlerFactory
{
public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path)
{
var view = base.GetHandler(context, requestType, virtualPath, path) as Page;
if (view == null) return view;
DependencyInjection.Container.BuildUp(view.GetType(), view);
return view;
}
}
<httpHandlers>
<add path=*.aspx verb=* type=BlogsPrajeesh.WebForms.DI.UnityPageHandlerFactory />
<!–httpHandlers>
I have created an extension method on the container to register the dependencies while initializing the container
public static class DependencyRegistrations
{
public static void SetupRegistrations(this UnityContainer container)
{
container
.RegisterType<IHomeView, HomeViewNullObject>()
.RegisterType<IHomeService, HomeService>()
.RegisterType<HomePresenter>();
}
}
Later when the container is initialized you can call the SetupRegistrations methods on the container. container.SetupRegistrations();
A sample view – Presenter implementation can be done like.
public partial class Home : Page, IHomeView
{
private HomePresenter _presenter;
public new event EventHandler OnLoad;
[Dependency]
public HomePresenter Presenter
{
set { _presenter = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
_presenter.InitializeViewEvents();
if (OnLoad != null) OnLoad(this, EventArgs.Empty);
lblHello.Text = _presenter.GetMessage();
}
}
public class HomePresenter : AppPresenter<IHomeView>
{
private readonly IHomeService _homeService;
public HomePresenter([Dependency] IHomeService homeService)
{
_homeService = homeService;
}
public string GetMessage()
{
return _homeService.GetMessage();
}
public override void InitializeViewEvents()
{
View.OnLoad += new EventHandler(View_OnLoad);
}
}
Using this kind of an implementation allows you to completely unit test your ASP.NET web application.
[TestMethod]
public void GetMessageShouldRetrieveTheMessageFromTheRegisteredService()
{
var presenter = DependencyInjection.Container.Resolve<HomePresenter>();
Assert.IsFalse(string.IsNullOrEmpty(presenter.GetMessage()));
}
• Monday, July 11th, 2011
Template method pattern defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure. In your code if two or more methods in subclasses perform similar steps in the same order with different logic or steps you can make use of the extract template method refactoring steps to generalize the methods by extracting their steps into methods with identical signatures and pull up these to form the Template Method.
For e.g., the below given code samples simulate the withdrawal functionality on different bank accounts.
public class SavingsAccount
{
private readonly User _user;
private decimal _balance;
public SavingsAccount(User user)
{
_user = user;
}
public string GetUserName()
{
return _user.GetName();
}
public void SetBalance(decimal balance)
{
_balance = balance;
}
public void HasSufficientBalanceForTransfer(decimal amountToWithdraw)
{
if(amountToWithdraw > _balance)
throw new InsufficientBalancesException();
}
public decimal GetServiceChargeForWithdrawal()
{
return 0M;
}
public void WithdrawAmount(decimal amountToWithdraw)
{
_balance -= amountToWithdraw + GetServiceChargeForWithdrawal();
}
public decimal GetBalance()
{
return _balance;
}
}
public class CurrentAccount
{
private readonly User _user;
private decimal _balance;
public CurrentAccount(User user)
{
_user = user;
}
public string GetUserName()
{
return _user.GetName();
}
public void SetBalance(decimal balance)
{
_balance = balance;
}
public void HasSufficientBalanceForTransfer(decimal amountToWithdraw)
{
if(amountToWithdraw > _balance)
throw new InsufficientBalancesException();
}
public decimal GetServiceChargeForWithdrawal()
{
return 0M;
}
public void WithdrawAmount(decimal amountToWithdraw)
{
_balance -= amountToWithdraw + GetServiceChargeForWithdrawal();
}
public decimal GetBalance()
{
return _balance;
}
}
The test cases on the current account for the withdrawal function
[TestMethod]
[ExpectedException(typeof(InsufficientBalancesException))]
public void ifUserTriesToWithdrawMoreMoneyThanAvailableBalanceShouldThrowException()
{
var currentAccount = _bank.CreateSavingsAccount(_user);
const decimal balance = 100M;
currentAccount.SetBalance(balance);
const decimal amountToWithdraw = 500M;
currentAccount.HasSufficientBalanceForTransfer(amountToWithdraw);
}
[TestMethod]
public void currentAccountDoesNotDeductServiceChargeOnWithdrawal()
{
var currentAccount = _bank.CreateSavingsAccount(_user);
const decimal balance = 100M;
currentAccount.SetBalance(balance);
var serviceCharge = currentAccount.GetServiceChargeForWithdrawal();
Assert.IsTrue(serviceCharge == 0M);
}
[TestMethod]
public void ifUserTriesToWithdrawAmountAvailableInAccountShouldProccedWithTransaction()
{
var currentAccount = _bank.CreateSavingsAccount(_user);
const decimal balance = 100M;
currentAccount.SetBalance(balance);
const decimal amountToWithdraw = 50M;
currentAccount.WithdrawAmount(amountToWithdraw);
Assert.AreEqual(currentAccount.GetBalance(), 50M);
}
As you can see from the test code, the withdraw functionality follows a series of steps to complete the actual withdrawal of money from the account like checking available balances, calculating the service charge etc. We can try to apply the template method by generalizing these actions and pulling up the template method to an abstract Account class.
First we apply the Extract superclass refactoring to create a superclass that holds the template method.
After applying the refactoring our Current and Savings account classes now looks like.
public class CurrentAccount : Account
{
public CurrentAccount(User user)
{
_user = user;
}
public void HasSufficientBalanceForTransfer(decimal amountToWithdraw)
{
if(amountToWithdraw > _balance)
throw new InsufficientBalancesException();
}
public decimal GetServiceChargeForWithdrawal()
{
return 0M;
}
public void WithdrawAmount(decimal amountToWithdraw)
{
_balance -= amountToWithdraw + GetServiceChargeForWithdrawal();
}
}
public class SavingsAccount : Account
{
public SavingsAccount(User user)
{
_user = user;
}
public void HasSufficientBalanceForTransfer(decimal amountToWithdraw)
{
if(amountToWithdraw > _balance)
throw new InsufficientBalancesException();
}
public decimal GetServiceChargeForWithdrawal()
{
return 25M;
}
public void WithdrawAmount(decimal amountToWithdraw)
{
_balance -= amountToWithdraw + GetServiceChargeForWithdrawal();
}
}
Next we apply the pull members up refactoring to pull the generalized methods to the super class and then implement the abstract methods in the respective child classes.
The final output looks like.
public abstract class Account
{
protected User _user;
protected decimal _balance;
public string GetUserName()
{
return _user.GetName();
}
public void SetBalance(decimal balance)
{
_balance = balance;
}
public decimal GetBalance()
{
return _balance;
}
public abstract void HasSufficientBalanceForTransfer(decimal amountToWithdraw);
public abstract decimal GetServiceChargeForWithdrawal();
public void WithdrawAmount(decimal amountToWithdraw)
{
HasSufficientBalanceForTransfer(amountToWithdraw);
var serviceCharge = GetServiceChargeForWithdrawal();
_balance -= amountToWithdraw + serviceCharge;
}
}
public class CurrentAccount : Account
{
public CurrentAccount(User user)
{
_user = user;
}
public override void HasSufficientBalanceForTransfer(decimal amountToWithdraw)
{
if(amountToWithdraw > _balance)
throw new InsufficientBalancesException();
}
public override decimal GetServiceChargeForWithdrawal()
{
return 0M;
}
}
public class SavingsAccount : Account
{
public SavingsAccount(User user)
{
_user = user;
}
public override void HasSufficientBalanceForTransfer(decimal amountToWithdraw)
{
if(amountToWithdraw > _balance)
throw new InsufficientBalancesException();
}
public override decimal GetServiceChargeForWithdrawal()
{
return 25M;
}
}
Category: .Net, Agile/Scrum | Tags:  | Leave a Comment