Subscribe in a reader
Nermin's .Net - My Thoughts on .Net and Software Development
Nermin's .Net
My Thoughts on .Net and Software Development

Few more words on Chrome

September 3, 2008 02:58 by ndibek

If my previous post about Chrome has you thinking about it, but you are still unsure whether you would want a BETA software installed on your computer, following blog posts explains pretty much all of the features of the Chrome browser:

http://blogoscoped.com/google-chrome/ 

And it is all packaged in a nice visual story.

 

Enjoy! 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories:
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Google's Chrome Shines

September 2, 2008 07:15 by ndibek

So what is Google Chrome?  It is a new Web Browser. But before you say: "Enough, I can't keep track of IE7/8, Mozilla, Safari, now I have to take a look at yet another browser!!!", there is something interesting and different about this one.

 It appears that the Google team has been writing a browser from scratch, not worrying about baggage like what is found in IE or Mozilla.  It is Open Source so they have been able to take existing bits and pieces from other projects as needed - shortening development time, and at the same time adding a ton of completely new stuff.

First reason to take a look at this browser would be:

- How many times do you deal with IE that fails to load one of the tabs, end up locking the whole browser process, and there is nothing you can do about it but kill the process.  Mozilla is a bit better, but to me it seems that it is "allergic" to Flash.  

Chrome's Solution:  Each Page loads in its own Process.  There is no way that JavaScript failing on one page can hang the whole browser - you just get what they call "Unhappy Tab".  Each Tab manages its own memory and garbage collection, assuring that once the tab is closed all of its memory is released, which is not the case with the other 2 browsers.

Talking about JavaScript - they have build a brand new Virtual Machine for their JavaScript that besides supporting objects also adds support for classes in JavaScript.  Not just that but all of the existing JavaScript objects are assigned to "hidden" JavaScript classes, allowing categorization, and caching.  In addition, there is a built-in performance advantage of VM where JavaScript is compiled and then binary is re-used instead of re-interpreted each time JavaScript is re-executed is priceless.  Google site points to huge performance increases.  I have not run a numbers, but just a visual rendering part of UI components that are generated by JavaScript looks awesome.  I have run Chrome against the ExtJs.com demos - ExtJs being most JavaScript intensive UI/Ajax library, and have not seen yet such a performance out of those components.

From that we move onto rendering engine.  Used with dozen or so web sites - it is flawless.  Smoothest page rendering, and there are no visual differences when compared to IE.  It appears that google.com cached searches help Chrome folks in their automated testing of the layout engine - they virtually have whole of the web at their fingertips.

and finally some typical Google touches:

- if I type "news." in my url bar, I get news.google.com, and news.yahoo.com in the dropdown below it and not 500 articles I have previously visited on those 2 web sites

- when I open a new tab in Chrome, by default I get a sidebar with my most used bookmarks, as well as thumbnails of my most visited pages, allowing me to open one with a single click (image below)

 

All in all this product has left an excellent first impression and even though it is still beta I would recommend everyone to check it out. 

 http://www.google.com/chrome

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: General | Tools
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

SVN Bridge from CodePlex

August 26, 2008 03:46 by ndibek

Working with CodePlex on one of the projects I was faced with dilemma – download TFS explorer to get the latest source code from their TFS server, or…
I was about to give up and download/run a 300 TFS Explorer on my latest development VPC image (project required some beta MS tools; hence the VPC as a development platform, but that is story for some other time).  But then I noticed following text:

!! Warning !! - If you use the Team Explorer client then it will add source control binding information into your project files. When users download your source code and try to open it in Visual Studio they will get error messages because of the source control bindings. You can use any of the other available source control clients as an alternative.


So the Codeplex folks do not recommend using Team Explorer?!  Other options included several console tools, and one mentioned TortoiseSVN – which I am using anyways on a daily basis.  It appeared that you can use TortoiseSVN for any of your CodePlex source control operations, as long as you install and sun this SVN Bridge service on your local computer.


So I gave it a try - It is truly simple.  You download the executable from the Codeplex’s site, and run it – that creates a service that runs and can be seen in your windows trey. This service runs as a “fake” SVN server that runs on port 8081 by default and does nothing but translate SVN API calls to remote TFS.

You might wonder how does a call to the “local” SVN repository gets directed to correct CodePlex TFS server.  It is simple:
1)    You create a folder which will contain your project source from TFS.
2)    Right click on the folder in Win Explorer, and using SVN Checkout command of your Tortoise client, bring up the Checkout dialog.
3)    The format for your checkout URI is then:
http://localhost:8081/<CodePlex TFS Server domain>/<CodePlex Project Name>


And that is it.  I have tried a number of TortoiseSVN commands including “Repo-browser”.  Everything seems to work fine.  In the weeks and months ahead I will continue to use and evaluate this tool, but as it stands now, it was extremely easy to configure and use.  I highly recommend it.

kick it on DotNetKicks.com


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: General | Tools
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Finally a viable 3rd party candidate

August 24, 2008 12:25 by ndibek

Years in making but it has finally come true:

 

 


Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: General
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

RhinoMocks 3.5 AAA Model

August 22, 2008 03:58 by ndibek

Ayende has again proven why he is one of the most respected names in Alt.Net community.  Besides writing a book on language based DSLs, supporting Boo, and NHibernate, having a full time job, and writing one of the most informative blog publications, he has actually practically re-written RhinoMocks in this new version.  And with that RhinoMocks basically takes back the title of simplest and most productive dynamic mocking framework out there.

Take a look at an ASP.NET MVC test written with RhinoMocks 3.3: 

 

As you can see the test above uses a traditional Record & Replay model (referred to as R&P in the rest of this document), where in Record block we generally set our expectations, and then the Replay block is used to perform actions on object being tested,  allowing our Mock objects to execute and verify expectations.

Now let’s take a look at the same test written with RhinoMocks 3.5:

 



This test uses Arrange, Action and Assert model (AAA).  What you will notice first is that there are by far fewer lines needed to setup mocks.

In the AAA version there is no need to instantiate MockRepository, once you generate your Mock, or in this case Stub object, you can setup your expectations directly on the mock instance. Lines 21 and 22 in R&P version of the test are replaced by single line of code in AAA version – line 22.

You will also notice that we are using GenerateStub() instead of DynamicMock().  Put simply there is a difference between Mock and Stub objects and RhinoMocks recognizes that allowing us to write tests that better state their purpose.  For some of you scratching your heads, easiest way to describe the difference is to say that Mock objects are used to define expectations i.e: In this scenario I expect method A() to be called with such and such parameters.  Mocks record and verify such expectations.  Stubs, on the other hand have a different purpose: they do not record or verify expectations, but rather allow us to “replace” the behavior, state of the “fake” object in order to utilize a test scenario.

In this case the behavior we want to stub is: “When GetCustomers() is called return the testCustomers list.”  You can see that AA version uses a Lambda expression to define the method being called.  Again the line 24 in AA version replaces lines 24-30 in R&P version.

And lastly at the end of the AAA version, as we have defined our expectation directly on the mock object itself (which replaced the record block), there is no need to define the Playback block either.  It is assumed that it follows the recorded assumptions.  Therefore the Playback section of the R&P model is comparable to Action and Assert sections of the AA model.

So as you can see our tests have dropped from 13 down to 7 lines of code.  Also due to a lot simpler mocking portion of the block tests are now lots easier to read and maintain.  I must add that this is only the portion of the new features Ayende is adding to RhinoMocks, and for more details I would refer you to go to RhinoMocks wiki as well as Ayende’s blog.  Personally I would like to congratulate him on making a good Dynamic Mocking tool great.

http://ayende.com/Wiki/Default.aspx?Page=Rhino%20Mocks%203.5&AspxAutoDetectCookieSupport=1#WhatsNewinRhinoMocksDF

 

 

  kick it on DotNetKicks.com


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: C# | Mock | TDD | Unit Testing
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

You might be spending too much time on Alt.net newsgroup if...

March 20, 2008 05:28 by ndibek

GMail flaggs you as a spammer!

At least that is what happened to Oren (who, Imust say contributes to at least 20% if the Alt.Net newsgroup messages, and there are thousands of them each month):

http://ayende.com/Blog/archive/2008/03/20/Email-habits.aspx

On the other hand it could be that a sheer number of his blog posts and thousands of subscriptions that are send all over the world contribute to this problem too.  I swear he writes these posts faster than I can read them.  When does that man go to sleep?

  

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Alt.Net
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

MVC Framework CTP 2

March 6, 2008 08:37 by ndibek
Jeffrey Palermo has just announced that the second release of Microsoft's ASP.NET MVC Framework is available now.  Download your copy from here.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: MVC | ASP.NET
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Less than one week to ReSharper 4.0 EAP

February 9, 2008 06:15 by ndibek

I can't express how excited I am about this new release of Resharper, which will allow us to work with .Net 3.5 features  - Lambda expressions, Extension Methods, Anonymous initializers, etc.

Based on this post from the Ilya Ryzhenkov, we should have a release before the end of the next week:

 http://resharper.blogspot.com/2008/01/resharper-4-eap-will-start-in-two-weeks.html


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ReSharper
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Second meeting of The Chicago Alt.Net group

February 9, 2008 02:45 by ndibek

This Thursday evening I met with over dozen of amazing .Net developers that share with me both excitement about future of software development and desire to learn and better ourselves.  We are all members of the AltDotNet  newsgroup and reside in Chicago area.  AltDotNet is a global movement and following is our mission statement:

We are a self-organizing, ad-hoc community of developers bound by a desire to improve ourselves, challenge assumptions, and help each other pursue excellence in the practice of software development.

Our movement is new. The conversation just started. All are welcome to shape and form the dialog in blogs and lists and face-to-face gatherings both local and global.

We met at Jaks Tap for a few hours of discussion, deciding where to go next, and how to build a community.  I am really happy to say that we are moving forward rather quickly.  We have acquired a domain for our future site already, and are in planning phases for building our web site.  Most likely we will use the "Code Camp Server", an open source project that is built using new ASP.NET MVC framework.  Few of us are also contributors to Code Camp Server.   Stay tuned for future anouncements and meantime feel free to join our mailing list.  Meantime if you wish to learn more about this movement please visit AltNetPedia.

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: ,
Categories: Alt.Net
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Fluent Stubs

February 7, 2008 05:20 by ndibek

Refactoring has become a common practice amongst many developers I work with.  Why refactor?

Well, first it takes the pressure of off design phase of project in a sense.  You do not have spend ton of time upfront designing the code and assuring that you thought of every detail before you even write a single line of code.  You simply get a rough design and start coding right away, knowing that as you implement the system, get more familiar with the code, you will notice better patterns and refactor the code towards them.

We all know that, if done right, refactoring leads to simpler smaller code base that is easier to maintain.  Meantime we use Unit Tests to assure that the refactoring we performed did not change the outcome or results that our code produces.  I have been following this practice for a while and it has kept me out of trouble.

However what I realized over time is that the Unit Tests themselves become more complex, with too much duplication, and too hard to read.

Take for example this problem I had recently at the client I am working for.  We inherited a “failed” project (story of my life – I always end up coming in to fix someone else’s mess, but enough about that), a project that  another consulting company has given up on after complicating the matter a bit first.

No, they did not use code refactoring, they did not have unit tests, instead they have used code generation tool to “save time”.  It is just that their code generation templates were not really thought through.  Now we have a complex system, with a lot of bugs to clean and lot of code to refactor.  And yes, in order to refactor we had to start writing unit tests to support it.

Well all of their Business Objects are initialized by making a DB call in their constructor that uses Datasets as the DTOs that transfer that data from the DAL (I know what you are going to say now – but sometimes you have to work with what you have – we have to bring this site online!).

But lets start with an example.  Lets say I had a bussiness object called ShoppingCart and that it contained a list Product sand a list of Options for eaach product.  In the constructor of the ShoppingCart, they would have an instance of a ShoppingCartData object that would have a method callled ExecuteDataSet() which although the name does not state it returns all Products and their options that belong to this shopping cart.  Then the code inside of the dataset woule lop through the tables and populate both object lists, something like:

ShoppingCartData _shoppingCartData = new ShoppingCartData();

public ShoppingCart()

{

     DataSet ds = _shoppingCartData.ExecuteDataSet();

     foreach(DataRowView in ds.Tables[0].Rows){

}

So in order to write tests against these objects I had to mock the DAL call and replace the DataSet that the DB would return with my own.   As you can see ShoppingCartData was not injected, nor did it have an interface so for mocking part I had to bring the big guns – TypeMock. 

Mock data = MockManager.Mock(typeof(ShoppingCartData));

cartData.ExpectAndReturn("ExecuteDataSet",cartDataSetStub); 

So mocking the Db call and taking DB out of eqation was easy.  Even generating the stub data for the tests was not the problem.  You might have read one of my previos blogs where I wrote about this little code generation tool that helped me generate DataTable Stub objects just by runnig the sql :

http://www.nermins.net/post/2007/07/Mock-ADONET-with-ease-using-IDataReader-Stub-objects.aspx

In that previous example I take advantage of DataTable CreateReader() method to generate IDataReader Stubs.  However in this case my Stub objects are DataSets, so I can use these table Stubs directly.

I also have the code for that tool available on the google code site:

http://code.google.com/p/data-stub-generator/

So, if setting up mocking and setting up Stub data was not the problem then what was? I had to write a number of tests against each of the BO including Shopping Cart.  That meant setting up the data for the cartTadaSetsTub DataSet.  I also wanted my code genaration tool to generate tables with one and couple of tests records that represent the dafault /valid data, and then explicitly set the values/cells that were needed for the test in the test itself.

For example let’s say that we have the rule that says that shopping cart can not check out if there is at least on item that has been discontinued since we placed it on the shopping cart.  That means that my table returning Products data would have to have one record that has “Discountinued” column set to true.  So let’s take a look at the code needeed for that:

DataSet cartDataSetStub = new DataSet();

DataTable products = new ShoppingCartProductsStub();

products.AddDefaultRow();

products.Rows[0][“Discountinued”] = true;

DataTable options = new ShoppingCartOptionsStub();

cartDataSetStub.Tables.Add(products);

cartDataSetStub.Tables.Add(options);

 

Mock cartData = MockManager.Mock(typeof(ShoppingCartData));

//Assure that _shoppingCartData.ExecuteDataSet()

//returns our cartDataSetStub instead of calling DB

cartData.ExpectAndReturn("ExecuteDataSet",cartDataSetStub); 

ShoppingCart cart = new ShoppingCart(); 

Assert.That(cart.CanCheckOut, Is.EqualTo(false));  

First 7 lines of code are there just to simply setup “fake” output from the database.  There is more code in the part that sets up the data for the test than the actual test.  And actually it could have been worse if I have not used the generated table stub objects ShoppingCartProductsStub and ShoppingCartOptionsStub.  All that code crowds the test and doesn’t really expresss my intention – it is hard to read.  So what did I do to solve that?

Fluent Interfaces to the rescue!  How about this for a change:

Mock cartData = MockManager.Mock(typeof(ShoppingCartData));

cartData.ExpectAndReturn(

    "ExecuteDataSet",

     Stub.GetDataSet(

         ShoppingCartProductsStub.Empty().AddDefaultRow()

            .AtRow(0)

            .InCell(“Discountinued”)

            .SetValue(true),

         ShoppingCartOptionsStub.Empty())); 

 

ShoppingCart cart = new ShoppingCart(); 

Assert.That(cart.CanCheckOut, Is.EqualTo(false)); 

Four statements above are functionaly equivalent to that code mesh in previous example.  And as you can see you can simply read the code to figure what it does!  We are generating DataSet with two tables where on the first table we add the default row of data and then set the cell “Discontinued” to false.  Second table is empty.  And that is it.

So how do these fluent interfaces work?  What is the logic behind them?  Well simply put, lest take a look at the methods that we use to manipulate an object  (StubTable in this case).  In the example above those methods are:  Empty(), AddDefaultRow(), AtRow(int rowNo), InCell(string cellName), SetValue(object value).  Generaly these methods would return void.  In fluent programing they return the object itself or better an interface that implements these other methods.  So first I created the object called StubTable:

public class StubTable : DataTable

{

    private int _currRow = 0;

    private string _currCell = string.Empty;

    protected StubTable(){}

    public static StubTable Empty()

    {

        return new StubTable();

    }

    public StubTable AtRow(int rowNo)

    {

        _currRow = rowNo;

        return this;

    }

    public StubTable InCell(string cellName)

    {

        _currCell = cellName;

        return this;

    }

    public StubTable SetValue(object value)

    {

        Rows[_currRow][_currCell] = value;

        return this;

    }

    public StubTable AddRow(params object[] values)

    {

        Rows.Add(values);

        return this;

    } 

}

  

Then the generated SoppingCartProducts and ShoppingCartOptions DataTables inherit from Stub table and are modified to look like this:

public class ShoppingCartProductsStub : StubTable

{

    public new static ShoppingCartProductsStub Empty()

    {

        return new ShoppingCartProductsStub();

    }

    protected ShoppingCartProductsStub()

    {

        InitColumns();

    }

    private void InitColumns()

    {

        Columns.Add("ShopingCartID", typeof(Int32));

        Columns.Add("ProductID", typeof(Int32));

        Columns.Add("ProductName", typeof(String));

        Columns.Add("ProductNumber", typeof(String));

        Columns.Add("ProductQty", typeof(Int32));

        Columns.Add("Price", typeof(Decimal));

        Columns.Add("PromotionPrice", typeof(Decimal));

        Columns.Add("Discontinued", typeof(Boolean));

       

    }

    public StubTable AddDefaultProduct()

    {

        Rows.Add(705582, 1, "Round Cook-N-Dine Built-in Cook Top", "MO-60", 5,

          decimal.Parse("1200.9400000000000"), decimal.Parse("1200.9400000000000"),false);

        return this;

    }

}

And Finaly Our Stb class that builds and returns th