Monday, December 27, 2010

Average Cycle Time of Workitems

Find below a query that shows the average Cycle Time per state, you can store the results in a temporary table and join it to provide averages to help in value stream mapping.

 

image Cycle Time Per Sprint
image

The bulk of the work is done by the query below


   1:  WITH cteStateChange(rowId, tpId, wiId, [State], PrevState, UpdTime) AS(
   2:      SELECT Row_Number() OVER(Order by wi.TeamProjectSK, wi.System_id, wi.System_Rev) 
   3:          , wi.TeamProjectSK
   4:          , wi.System_Id
   5:          , wi.System_State
   6:          , wi.PreviousState 
   7:          , wi.System_ChangedDate
   8:      FROM dbo.DimWorkItem wi
   9:      INNER JOIN dbo.FactWorkItemHistory wih
  10:          ON wih.WorkItemSK = wi.WorkItemSK
  11:          AND wih.TeamProjectSK = wi.TeamProjectSK
  12:      WHERE 1=1
  13:      AND (wih.StateChangeCount = 1)
  14:  )

Wednesday, December 22, 2010

Visualize your workflow with Team Foundation Server

I created a custom report for Team Foundation Sever 2010 to visualize your workflow in order to identify bottlenecks

 

Identify bottle necks

image

This indicates a bottleneck in testing there is work stacking up for the QA department.

This report will tell you at a glance where to take action.

Inspect Flow

As you see in the picture above no clear “steps” for committed are noticeable in the above chart. The chart below shows a more healthy example.

image

You also notice that there is an inventory of untested items building up.

Tuesday, November 30, 2010

Keep Assembly version same as build number

I have been struggling all afernoon with Team Foundation Server 2010 Custom Activities to keep the BuildNumber and the AssemblyVersions in Sync.
Apperantly System.Version is not serializable so the value gets lost when going into the Run On Agent Sequence.
As a startiong point I used the code of Ewald Hoffman. Original Article: http://www.ewaldhofman.nl/post/2010/04/20/Customize-Team-Build-2010-e28093-Part-1-Introduction.aspx
Step 1: Create the Version Generator (+ offcource the necessary unit tests Smile)…
   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace SharpSolutions.Tfs.Build.BuildTasks
   7:  {
   8:      public sealed class AssemblyVersionGenerator: IAssemblyVersionGenerator
   9:      {
  10:          /// <summary>
  11:          /// Generatas a new Assembly version
  12:          /// int the following format: Major.Minor.Build.Revision
  13:          /// Major: same as current version
  14:          /// Minor: same as current version
  15:          /// Build: 2 digit year since 2000* 1000 + day of year eg 10001 = Build run on 1 jan 2010
  16:          /// Revision: seconds since midnight
  17:          /// </summary>
  18:          /// <param name="currentVersion">used to retrieve current major and minor version</param>
  19:          /// <returns>A new Assembly version</returns>
  20:          public Version Generate(Version currentVersion)
  21:          {
  22:              //If we did not force now use the real now
  23:              //O_o get it?
  24:              DateTime now = ((IAssemblyVersionGenerator)this).Now == default(DateTime)? DateTime.Now: ((IAssemblyVersionGenerator)this).Now;
  25:              int major = currentVersion.Major;
  26:              int minor = currentVersion.Minor;
  27:              int build = (now.Year % 2000) * 1000 + now.DayOfYear;
  28:              int revision = (int)(now - new DateTime(now.Year, now.Month, now.Day, 0, 0, 0)).TotalSeconds / 10;
  29:   
  30:              return new Version(major, minor, build, revision);
  31:          }
  32:   
  33:          DateTime IAssemblyVersionGenerator.Now { get; set; }
  34:      }
  35:  }



2. Create a new Code Activity. Offcourse you can easily implement your own version of IAssemblyVersionGenerator



   1:  using System;
   2:  using System.Activities;
   3:  using Microsoft.TeamFoundation.Build.Client;
   4:  using Microsoft.TeamFoundation.Build.Workflow.Activities;
   5:   
   6:  namespace SharpSolutions.Tfs.Build.BuildTasks.Activities
   7:  {
   8:      [BuildActivity(HostEnvironmentOption.Controller)]
   9:      public sealed class GenerateAssemblyNumber : CodeActivity<string>
  10:      {
  11:          private IAssemblyVersionGenerator versionGenerator = new AssemblyVersionGenerator();
  12:          
  13:          [RequiredArgument]
  14:          public InArgument<string> AssemblyInfoFileMask { get; set; }
  15:   
  16:          [RequiredArgument]
  17:          public InArgument<string> Version { get; set; }
  18:   
  19:          [RequiredArgument]
  20:          public InArgument<IBuildDetail> BuildDetail { get; set; }
  21:          
  22:          protected override string Execute(CodeActivityContext context)
  23:          {
  24:              string assemblyInfoFileMask = context.GetValue(this.AssemblyInfoFileMask);
  25:              string version = context.GetValue(this.Version);
  26:   
  27:              Version currentVersion = new Version(version);
  28:              Version newVersion = versionGenerator.Generate(currentVersion);
  29:              context.TrackBuildMessage(string.Format("New Version is {0}", newVersion.ToString()));
  30:  
  31:              return newVersion.ToString();
  32:          }
  33:      }
  34:  }



Step 3: Update the version number in the AssemblyInfo.cs



   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Activities;
   6:  using System.Text.RegularExpressions;
   7:  using System.IO;
   8:  using Microsoft.TeamFoundation.Build.Client
   9:  using Microsoft.TeamFoundation.Build.Workflow.Activities;
  10:   
  11:  namespace SharpSolutions.Tfs.Build.BuildTasks.Activities
  12:  {
  13:      [BuildActivity(HostEnvironmentOption.Agent)]
  14:      public sealed class UpdateAssemblyVersion : CodeActivity
  15:      {
  16:          [RequiredArgument]
  17:          public InArgument<string> VersionNumber { get; set; }
  18:   
  19:          [RequiredArgument]
  20:          public InArgument<string> AssemblyInfoFileMask { get; set; }
  21:          
  22:          [RequiredArgument]
  23:          public InArgument<string> SourcesDirectory { get; set; }
  24:   
  25:          // If your activity returns a value, derive from CodeActivity<TResult>
  26:          // and return the value from the Execute method.
  27:          protected override void Execute(CodeActivityContext context)
  28:          {
  29:              // Obtain the runtime value of the input arguments
  30:              string sourcesDirectory = context.GetValue(this.SourcesDirectory);
  31:              string assemblyInfoFileMask = context.GetValue(this.AssemblyInfoFileMask);
  32:              Version newVersion = new Version(context.GetValue(this.VersionNumber));
  33:              
  34:              // Get all AssemblyInfo files
  35:              foreach (string file in Directory.EnumerateFiles(sourcesDirectory, assemblyInfoFileMask, SearchOption.AllDirectories))
  36:              {
  37:                  // Read the text from the AssemblyInfo file
  38:                  string assemblyInfoVersionText = File.ReadAllText(file);
  39:   
  40:                  string updatedContents = Utilities.UpdateAssemblyVersion(assemblyInfoVersionText, newVersion);
  41:   
  42:                  File.WriteAllText(file, updatedContents);
  43:              }
  44:          }
  45:   
  46:      }
  47:  }

Monday, November 29, 2010

Formatting Source code for BLOG

Reminder to myself since I always have to search for it over and over: http://www.manoli.net/csharpformat/format.aspx

5S for .NET

I just finished Implementing lean software development: From Concept to Cash. In chapter 8: Quality (page 192) We find the 5S’s for Java find below my interpretation for .NET.

  • Sort (Seiri): Reduce the size of the code base. Throw away everything that is not needed. Remove:
    1. Dead Code
    2. Unused using statements
    3. Unused references
    4. Unused variables
    5. Unused Methods
    6. Unused Classes
    7. Refactor redundant/duplicate code
    8. Delete code in comments
    9. Delete or fix Ignored Unit Tests
  • Systematize (Seiton): Organize projects and packages. Have a place for everything and everything in its place
    • Resolve package dependency cycles
    • Minimize dependencies
  • Shine (Seiso): Clean up. Problems are more visible when everything is neat and clean.
    • Resolve unit test failures (Pass rate should be 100%)
    • Improve unit test coverage (> 80%)
    • Improve Unit test performance
    • Check duration to run all tests
    • Resolve compiler warnings
    • Resolve TODO’s
    • Resolve FxCop Warnings
    • Refactor methods that are too long
    • Refactor methods where Cyclomatic Complexity > 10
  • Standardize (Seiketsu): Once you get a clean slate, keep it that way. Reduce complexity over time to improve ease of maintenance.
  • Sustain (Shitsuke): Use and follow standard procedures
    • Integrate FxCop in daily build
    • Fail Continuous integration build on unit test failure (Gated Check ins)

These criteria can easily be found using ndepend which is word its price in gold

Wednesday, November 24, 2010

Team Foundation Server 2010 MDX to exclude the weekends

 

WITH 
SET [WeekDays]
AS Filter(
[Date].[Date].[Date]
, COUNT(WTD([Date].[Year - Week - Date Hierarchy])) <> 1
AND COUNT(WTD([Date].[Year - Week - Date Hierarchy])) <> 7
)

SET [DateRangeFrom]
AS FILTER([WeekDays]
, [WeekDays].CurrentMember.Member_Value >= CDATE("11/17/2010")
)

SELECT {
[Measures].[Work Item Count],[Measures].[Revision Count]

}
ON COLUMNS,{
[DateRangeFrom]
// [Date].[Date].[Date]
// , WTD([Date].[Year - Week - Date Hierarchy].CurrentMember)
//
}

ON ROWS
FROM [Team System]

Tuesday, August 10, 2010

TDD Example Write function that calcutates a Fibonacci number

Step 1:

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:     Func<int, int> fib = null;
   4:   
   5:     Assert.AreEqual(0, fib(0));
   6:  }
Step 2:

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:     Func<int, int> fib = (n) => { return n; };
   4:   
   5:     Assert.AreEqual(0, fib(0));
   6:  }
Wee first test case passed!
Step 3: Adding another testcase

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => { return n; };
   4:   
   5:   
   6:      Assert.AreEqual(0, fib(0));
   7:      Assert.AreEqual(1, fib(1));
   8:  }
Works again
Step 4: Removing duplication in the asserts
   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => { return n; };
   4:   
   5:      Assert.AreEqual(0, fib(0));
   6:      Assert.AreEqual(1, fib(1));
   7:  }
Refactored gives:

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => {
   4:          return n;
   5:      };
   6:   
   7:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
   8:                  {0 , 0},
   9:                  {1 , 1},
  10:              };
  11:   
  12:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  13:      {
  14:          Assert.AreEqual(row.Value, fib(row.Key));
  15:      }
  16:  }
Step 5: Adding another testcase

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => {
   4:          return n;
   5:      };
   6:   
   7:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
   8:                  {0 , 0},
   9:                  {1 , 1},
  10:                  {2 , 1},
  11:              };
  12:   
  13:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  14:      {
  15:          Assert.AreEqual(row.Value, fib(row.Key));
  16:      }
  17:  }
Woops test failed!
Ok lets fix it:

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => {
   4:          if (n < 2) return n;
   5:          return 1;
   6:      };
   7:   
   8:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
   9:                  {0 , 0},
  10:                  {1 , 1},
  11:                  {2 , 1},
  12:              };
  13:   
  14:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  15:      {
  16:          Assert.AreEqual(row.Value, fib(row.Key));
  17:      }
  18:  }
Test Fixed!
Step 6: Adding another test case and taking 2 steps at the time since 1 will never equal 2 but 1 = 2-1 and 2 = 3-1 and thus return n-1 will do the trick for now

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => {
   4:          if (n < 2) return n;
   5:          return n - 1;
   6:      };
   7:   
   8:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
   9:                  {0 , 0},
  10:                  {1 , 1},
  11:                  {2 , 1},
  12:                  {3 , 2}
  13:              };
  14:   
  15:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  16:      {
  17:          Assert.AreEqual(row.Value, fib(row.Key));
  18:      }
  19:  }
 
 
Step 7: adding 2 more test cases (since the next we add will work fine too :))


   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => {
   4:          if (n < 2) return n;
   5:          return n - 1;
   6:      };
   7:   
   8:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
   9:                  {0 , 0},
  10:                  {1 , 1},
  11:                  {2 , 1},
  12:                  {3 , 2},
  13:                  {4 , 3},
  14:                  {5 , 5}
  15:              };
  16:   
  17:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  18:      {
  19:          Assert.AreEqual(row.Value, fib(row.Key));
  20:      }
  21:  }
Test Fails again (the test case marked in red)
The solution (fast forwarded):
Because 5 = 2 + 3
From the testcases we can see that fib(3) = 2 and fib(4)=3
And thus 5 = fib(3) + fib(4)
3 = 5 - 2 and 4 = 5 - 1
5 = n and this 5 = fib(n-2) + fib(n-1)

   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = (n) => {
   4:          if (n < 2) return n;
   5:          return fib(n - 1) + fib(n - 2);
   6:      };
   7:   
   8:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
   9:                  {0 , 0},
  10:                  {1 , 1},
  11:                  {2 , 1},
  12:                  {3 , 2},
  13:                  {4 , 3},
  14:                  {5 , 5}
  15:              };
  16:   
  17:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  18:      {
  19:          Assert.AreEqual(row.Value, fib(row.Key));
  20:      }
  21:  }
Does not compile :( Error: use of unsigned variable
The fix:
   1:  [TestMethod]
   2:  public void FibonacciSequanceTest(){
   3:      Func<int, int> fib = null;
   4:          fib = (n) => {
   5:          if (n < 2) return n;
   6:          return fib(n - 2) + fib(n - 1);
   7:      };
   8:   
   9:      Dictionary<int, int> fibonacciSequence = new Dictionary<int, int>{
  10:                  {0 , 0},
  11:                  {1 , 1},
  12:                  {2 , 1},
  13:                  {3 , 2},
  14:                  {4 , 3},
  15:                  {5 , 5}
  16:              };
  17:   
  18:      foreach (KeyValuePair<int, int> row in fibonacciSequence)
  19:      {
  20:          Assert.AreEqual(row.Value, fib(row.Key));
  21:      }
  22:  }

Et voila done!

Friday, April 02, 2010

Software Estimation

McConnell suggests in "Rapid Development: Taming Wild Software Schedules" that on large projecs the actual cost of coding and unit testing is 15% of the time spent.

So for a software estimation a good rule of thumb is
Analyse: 50%
Build: 15%
Test: 35%

Jack Reeves takes another perspective on this he says that source code is actually a design document and that the compiling and unit testing is the building (construction). So we can conclude that Construction of Software is actually very cheap and in software the design is the most costly activity in contrast with manufacturing and construction (engineering) where construction is the most expensive activity.

Source: Martin Fowler: http://martinfowler.com/articles/newMethodology.html

Thursday, March 18, 2010

Error when running tests: Unable to load one or more of the requested types

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information..

1. Clean the solution
2. Close Visual studio
3. Delete all the bin en obj folders
4. Try again

Monday, March 15, 2010

Sharepoint configuration wizard fails after sysprep

If you sysprep a machine on which you installed sharepoint and ran the configuration wizard and you try to run it again you get the following error (after you ran the sp_dopserver and sp_addserver stored procedures):

03/05/2010 17:16:12 8 ERR Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: password
at Microsoft.SharePoint.Administration.SPProcessIdentity.Update()
at Microsoft.SharePoint.Administration.SPApplicationPool.Update()
at Microsoft.SharePoint.Administration.SPWebApplication.CreateDefaultInstance(SPWebService service, Guid id, String applicationPoolId, IdentityType identityType, String applicationPoolUsername, SecureString applicationPoolPassword, String iisServerComment, Boolean secureSocketsLayer, String iisHostHeader, Int32 iisPort, Boolean iisAllowAnonymous, DirectoryInfo iisRootDirectory, Uri defaultZoneUri, Boolean iisEnsureNTLM, Boolean createDatabase, String databaseServer, String databaseName, String databaseUsername, String databasePassword, SPSearchServiceInstance searchServiceInstance, Boolean isPaired, Boolean autoActivateFeatures)
at Microsoft.SharePoint.Administration.SPAdministrationWebApplication.CreateDefaultInstance(SqlConnectionStringBuilder administrationContentDatabase, SPWebService adminService, IdentityType identityType, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.Administration.SPFarm.CreateAdministrationWebService(SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.Administration.SPFarm.CreateBasicServices(SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()
at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()


This is related to the fact that there are allready Application pools created. if you delete the earlier created applicaiton pools and websites you should be able to run the wizard without errors.

Thursday, March 11, 2010

Ax Business Connector .NET Unable to log on to Microsoft Dynamics AX.

LogonFailedException: Unable to log on to Microsoft Dynamics AX.

Method signature
public void LogonAs(
string user,
string domain,
NetworkCredential bcProxyCredentials,
string company,
string language,
string objectServer,
string configuration
);

When using the logon as method of the Business Connector .NET you face a lot off issues. After searching on the net I found that almost everyone forces the bcProxyCredentials but actually this not the way it is supposed to be used.

but here the MSDN documentation contains an error:

bcProxyCredentials
Credentials of the Business Connector Proxy user used to authenticate and enable the use of LogonAs.

You can create a NetworkCredential object with the following code:

System.Net.NetworkCredential creds = new System.Net.NetworkCredential(
ADUserName, ADUserPassword, ADDomain)The NetworkCredential parameters must match the Business Connector Proxy user set in the Business Connector Proxy dialog box: To verify your settings go to the Administration pane, click Setup, click Security, and then select BusinessConnectorProxy.

the part in bold is wrong. If you open the client application got the Administration pane > Security > System Service Accounts and there you can set the Business Connector Proxy accound and you can perform the LogonAs method to imperonate another user.

From the installation guide:

Some components require that the .NET Business Connector be configured to connect to Microsoft Dynamics AX with a proxy account. The use of a proxy enables the .NET Business Connector to connect on behalf of Microsoft Dynamics AX users when authenticating with an AOS instance.

Next you should be able to use the LogonAs method to logon as any valid Axapta user

Edit: if you want to use the user that is running the process as the proxy account pass null to the LogonAs method for the bcProxyCredentials parameter

Friday, March 05, 2010

Booting from a VHD

With windows 7 and windows 2008 it is possible to boot from a hyper-v virtual disk

I usually set up an image with hyper-v and sysprep it then follow these steps to add it to your bootloader

C:\Windows\system32>bcdedit /copy {current} /d "JELLE-DEV"
The entry was successfully copied to {8208ac27-0bca-11df-8dbb-a0ef01535d7b}.

Copy the GUID that is

bcdedit /set {guid} device vhd=[locate]\image.vhd
bcdedit /set {guid} osdevice vhd=[locate]\image.vhd

Wednesday, March 03, 2010

Webcam access in Silverlight 4

Code snippet to show webcam capture in silverlight 4


CaptureDeviceConfiguration.RequestDeviceAccess();
CaptureSource _capture = new CaptureSource();
_capture.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
_capture.Start();
VideoBrush videoBrush = new VideoBrush();
videoBrush.Stretch = Stretch.Uniform;
videoBrush.SetSource(_capture);
rectVideo.Fill = videoBrush;
rectVideo.UpdateLayout();


Getting the output and resizing it to have a format of a picture that can be used in a profile


_capture.AsyncCaptureImage(img =>
{
_capture.Stop();
TranslateTransform tt = new TranslateTransform();

tt.Y = -73.5;
tt.X = -125;
WriteableBitmap bitmap = new WriteableBitmap(70, 93);

bitmap.Render(rectVideo, tt);
bitmap.Invalidate();
frameImage.Source = bitmap;
_capture.Start();
});

Friday, February 26, 2010

MVP in asp .net / sharepoint

The view interface



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

namespace SharpSoutions.MVP
{
public interface IView
{
Model DataSource { get; set; }
void DataBind();
void UpdateModel();

event EventHandler Saved;
}
}




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpSoutions.MVP.Domain;

namespace SharpSoutions.MVP
{
[Serializable]
public class Model
{
public Person NewPerson { get; set; }

public Title[] Titles { get; set; }
}
}


The presenter



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpSoutions.MVP.Domain;
using System.Diagnostics;

namespace SharpSoutions.MVP
{
public class Presenter
{
private Data.IRepository<Title> titleRepository;
private Data.IRepository<Person> personRepository;


public Presenter(Data.IRepository<Title> titleRepository, Data.IRepository<Person> personRepository)
{
Trace.TraceInformation("Begin Presenter.Ctor");
this.titleRepository = titleRepository;
this.personRepository = personRepository;

this.Model = new Model();
this.Model.NewPerson = new Person();
Trace.TraceInformation("End Presenter.Ctor");
}

public Model Model { get; set; }

public IView View { get; set; }

/// <summary>
/// Init populates the "static" data
/// These are the data that is shown in dropdown boxes etc
/// </summary>
/// <param name="mockView"></param>
public void Init(IView view)
{
Trace.TraceInformation("Begin Presenter.Init");
AttachView(view);
this.View.DataSource = this.Model;

this.Model.Titles = this.titleRepository.Query();

this.View.DataBind();
Trace.TraceInformation("End Presenter.Init");
}

public void AttachView(IView view) {
this.View = view;
this.View.Saved += new EventHandler(View_Saved);

}

void View_Saved(object sender, EventArgs e)
{
System.Diagnostics.Trace.TraceInformation("Begin Presenter.View_Saved");
this.Save();
System.Diagnostics.Trace.TraceInformation("End Presenter.View_Saved");
}

public void Save()
{
System.Diagnostics.Trace.TraceInformation("Begin Presenter.Save");
this.View.UpdateModel();

personRepository.Update(this.Model.NewPerson);
System.Diagnostics.Trace.TraceInformation("End Presenter.Save");
}
}
}


The View implementation



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SharpSoutions.MVP.Domain;

namespace SharpSoutions.MVP.Web
{
public partial class View : System.Web.UI.UserControl, IView
{


public Model DataSource{
get {
if (ViewState["d"] != null) {
return (Model)ViewState["d"];
}

return null;
}

set {
ViewState["d"] = value;
}
}

public override void DataBind()
{
System.Diagnostics.Trace.TraceInformation("Begin View.Databind");
base.DataBind();

TitleDropDown.DataSource = this.DataSource.Titles;
if (this.DataSource.NewPerson.Title != null) {
TitleDropDown.SelectedValue = this.DataSource.NewPerson.Title.Id.ToString();
}

TitleDropDown.DataTextField = "Name";
TitleDropDown.DataValueField = "Id";
TitleDropDown.DataBind();

nameTextbox.Text = this.DataSource.NewPerson.Name;
System.Diagnostics.Trace.TraceInformation("End View.Databind");
}


public void UpdateModel()
{
System.Diagnostics.Trace.TraceInformation("Begin View.UpdateModel");
this.DataSource.NewPerson.Name = nameTextbox.Text;
ListItem selectedTitle = TitleDropDown.SelectedItem;
this.DataSource.NewPerson.Title = new Title { Id = int.Parse(selectedTitle.Value), Name = selectedTitle.Text };
System.Diagnostics.Trace.TraceInformation("End View.UpdateModel");
}

public event EventHandler Committed;

protected void SaveButton_Click(object sender, EventArgs e)
{
System.Diagnostics.Trace.TraceInformation("Begin View.SaveButton_Click");

if (this.Saved != null) {
this.Saved(this, EventArgs.Empty);
}
System.Diagnostics.Trace.TraceInformation("End View.SaveButton_Click");
}


public event EventHandler Saved;
}
}

Sunday, January 31, 2010

Windows 7 RDP with blank password

I have a windows 7 HTPC setup atr home that is not part of my domain (in orderr if it reboots it reboots all by its self and dont ask for a password or ALT+CTRL+DELETE

but I wanted to work on it with RDP. But when I connected I gotr the following error:
"Logon failure: user account restriction. Possible reasons are blank passwords not allowed, logon hour restrictions, or a policy restriction has been enforced.". Even

Solution:
run secpol.msc /s and then under Security Settings -> Local Policies -> Security Options set the Accounts: Limit local account use of blank passwords to console logon only to disabled

Tuesday, January 19, 2010

Developer Interview question samples

FizzBuzz example.

A fizzbuzz is a small code sample/program that can be given to a developer to test his skills and knowledge about certain subjects


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

namespace ConsoleApplication1 {
public class ClassA {
public override string ToString() {
return "Hello from class A";
}
}

public class ClassB : ClassA {
public override string ToString() {
return "Hello from class B";
}
}

public class ClassC : ClassB {
public override string ToString() {
return "Hello from class C";
}
}

class Program {
static void Main(string[] args) {

ClassA first = new ClassC();
ClassC second = new ClassC();
ClassB third = (ClassB)second;
ClassA fourth = (ClassA)third;
object fifth = (object)fourth;

Console.WriteLine("1: " + first.ToString());
Console.WriteLine("2: " + second.ToString());
Console.WriteLine("3: " + third.ToString());
Console.WriteLine("4: " + fourth.ToString());
Console.WriteLine("5: " + fifth.ToString());
Console.ReadLine();
}


}
}