Showing posts with label vs2008. Show all posts
Showing posts with label vs2008. Show all posts

Friday, 29 October 2010

20 things that are wrong with TFS, and counting

We have recently spent a lot of time using TFS 2008, im no expert with this tool but it seems to me that there are lots of issues with it. Its not that im trying to do some TFS bashing but my last project using subversion didn't have source control problems.

As always though if anyone out there can put me right on any of these issues please do so.

  1. Renames and deletes don't always properly get merged between trunk and branch and back.
  2. We had really random deletion of files when doing a merge from a branch that has had a baseless merge applied to it, (files were randomly deleted off the trunk during merge) these files existed in our branch and the trunk before the merge, but were removed off the trunk after.
  3. After doing a baseless merge (using power tools on the cmd prompt) you then can't reliably use the TFS GUI to do things like merges, you must use the command line tools.
  4. Tooling just doesn't work when merging, files that have no conflicts just don't auto merge all the time and requires manual intervention for no reason. This is intolerable when refactoring and you have changed 100+ files.
  5. No ability to create patch files which can be subsequently applied to other branches.
  6. Changes to one branch cant be merged into another branch unless you go via the trunk.
  7. You cant merge workitems between branch and trunk, even though workitems are the main unit of work in TFS.
  8. Many standard features like rollback are not built in. It requires an additional 'power tools' download (There is no GUI for rollback)
  9. Can't seem to rollback to a given point in time, you can only rollback 1 changeset at a time, this just seems wrong to us?
  10. Using TFS built in diff tool reports lines that have no changes to have changes. And does not line up source and target very well making the tool very hard to use when trying to spot important differences.
  11. Doesn't know that files or folders have been added unless you tell TFS in the GUI, This can easily lead to files not getting checked in if they were not created in visual studio.
  12. The GUI doesn't always update to reflect the state of the source control, requires a refresh, this mainly effects the pending changes view.
  13. The UI is confusing in that if you are browsing the source and click on a file to open it, it opens the local copy not the one in source control. Also it doesn't tell you that the local is different from the one in source control.
  14. When you add a new mapping to your workspace the tool says 'do you want to update your workspace?' when you say yes it then goes and gets everything from your workspace and updates everything, you expect it to only get the changes due to the new mapping. this caused us quite a lot of confusion and wasted time, but luckily nothing was lost.
  15. Sometimes labels disappear, completely, as if they were never created.
  16. A label to label comparison does not always give the same results as a date to date comparison, even though the dates used are the same as when the labels were created.
  17. Checking out (not getting) the entire branch takes ages (40 minutes plus) even though the source is not really that big (70,500 files), we actually gave up in the end and 1/2 were checked out 1/2 were not.
  18. Deleting a branch took 40 minutes. Did a delete in TFS of the branch folder (took 10 mins) got a pending delete dialogue box, tried to check in the delete which failed with the error 'the local copy is not up to date', so we then undid the delete which took 20 mins, got the latest source (3 mins) and finally did the delete again (10 mins). Why cant TFS tell us up front the delete wont work because our file system is not up to date? and why when doing it in the TFS GUI does our local file system matter? especially since we had no pending changes?
  19. When you re-branch you lose your branch history.
  20. If you tolerate this, then your code will be next...

Wednesday, 27 January 2010

Spring.net and asp.mvc, Getting started with dependency injection

This small tutorial gives you the quickest route (that i know) to getting microsofts mvc working with spring.net for simple DI (Dependency injection) or IOC (Inversion of control) to aid in testing and maintanance. Yes i know spring.net can do much more but this is just a very basic how to.

Download Prerequesits
First get asp.mvc, download and install from here (im assuming you have vs2008 or like wise for this tutorial)
http://www.asp.net/mvc/download/
At the time of writing im using vs2008, xp and mvc 1
downloaded here
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b
but im sure mvc 2.0 would be much the same to set up DI

right click on your existing solution (or alternativly create a new one)
then add, new project, web, pick 'asp.net mvc web appication' from the list of templates contained
this will make a brand new mvc web app, all configured and ready to go, build and run it you should see the default mvc site out of the box.
now to get spring running and injecting goodness into it.

first download spring.net
http://www.springframework.net/download.html
im going for the latest production release 1.3.0

then download MVCContrib from
http://mvccontrib.codeplex.com/
im using the latest stable release for mvc 1.0 here
http://mvccontrib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33401
get both the main download and the extras package (the spring IOC assembalies are contained in the extras package)

reference the following assemblies from the solution: spring.core, mvcContrib and MCVContrib.spring

Substitute the default controller factory for the spring factory provided by mvcContrib
Add the following to the head of global.ascx
using Spring.Context.Support;
using MvcContrib.Spring;

add IOC to your global.ascx so that application_start creates a spring context

protected void Application_Start()
{
ConfigureIoC();
RegisterRoutes(RouteTable.Routes);
}

private static void ConfigureIoC()
{
ContextRegistry.RegisterContext(new XmlApplicationContext(false, "assembly://MvcApplication1/MvcApplication1/objects.xml"));

var ctx = ContextRegistry.GetContext();
SpringControllerFactory.Configure(ctx);

ControllerBuilder.Current.SetControllerFactory(typeof(SpringControllerFactory));
}

add an objects.xml file that will hold all the spring configuration

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net
http://www.springframework.net/xsd/spring-objects.xsd">
</objects>

This objects.xml must be an embedded resource into the assembly, right click the file, properties, and change it to an embedded resource. If you miss this step you will get an error stating 'Could not load file or assembly Spring.Core.....' basically stating that the assembly didn't contain the objects.xml, which is the dependency spring is looking for.

at this point if you ran the code you would get the error
No object named 'HomeController' is defined : Cannot find definition for object [HomeController]
This is good, it means that spring is looking for a definition of your home controller but cant find one.
so letes tell it about it

add this to your objects xml
<object id="HomeController" type="MvcApplication1.Controllers.HomeController, MvcApplication1">
</object>


now when you run the app you should get the same boring default mvc home page again, brilliant, looks like its working, now to test the dependency injection, this is what we have been waiting for.

Inject a custom object into the homeController
So the easiest way to demo this is to echo some text out onto the screen that comes from a dummy data
add 2 objects to the model folder

using System;
namespace MvcApplication1.Models
{
public interface IHelloDAO
{
String Hi();
}
}

namespace MvcApplication1.Models
{
public class HelloDAO : IHelloDAO
{
public string Hi()
{
return "This is data straight from HelloDAO";
}
}
}



now we are going to use this DAO (Data Access Object) in the controller to get some data from the model by using the Hi method on the IHello interface.
the class should now look like this
public class HomeController : Controller
{
public IHelloDAO HelloDAO { get; private set; }

public HomeController(IHelloDAO helloDAO)
{
HelloDAO = helloDAO;
}

public ActionResult Index()
{
//ViewData["Message"] = "Welcome to ASP.NET MVC!";
ViewData["Message"] = HelloDAO.Hi();

return View();
}

public ActionResult About()
{
return View();
}
}


We added a new constructor which takes an instance of IHelllo (this is the think that is being injected in), and we have used the instance to get the message by using HelloDAO.Hi()
finally import the relevent model namespace at the top of the file.

again if you were to run the app at this point you would get the following error:
Cannot instantiate a class that does not have a no-argument constructor [MvcApplication1.Controllers.HomeController].
which indicates quite clearly that the controller is not configured correctly. Basically spring is expecting a no argument constructor, but the real class dosent have one.

Configure Spring
Now all that remains is to wire the dependencies in the objects.xml which should now look like this

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net
http://www.springframework.net/xsd/spring-objects.xsd">

<object id="HomeController" type="MvcApplication1.Controllers.HomeController, MvcApplication1">
<constructor-arg ref="HelloDAO" />
</object>

<object id="HelloDAO" type="MvcApplication1.Models.HelloDAO, MvcApplication1">
</object>
</objects>

you can see we have added a parameterised constructor to the controller through wich we are injecting in an implementation of the HelloDAO interface.
The index remains the same as it was out of the box and should display our message instead of the default 'Welcome to ASP.NET MVC!'

lets run it.
magic, you have configured your first and hopefully not last controller through spring.net and asp.mvc

now your ready for part 2 (Spring.net and asp.mvc, even more dependency injection)