A better way to auto-run T4MVC when you build

T4MVC has always struggled with finding the right way of running automatically when you build.  Being a T4 template in your project, by default it just runs when you save it.  This is not great, because you really want it to rerun whenever you make a change that affects it: e.g. new controller action, new static file, …

So I had come up with a pretty crazy workaround (the AlwaysKeepTemplateDirty flag), described in details in this previous post (under “The T4 file automatically runs whenever you build”).  It’s a pretty hacky technique, which mostly works but has some nasty quirks:

  • You need to open and save it once to start the save ‘cycle’
  • You need to leave it open
  • It’s always marked as dirty, which is an annoyance.  The little ‘dirty star’ is always there, and when you close the project you’re always prompted if you want to save it, even though you didn’t change it.

Recently, Danish developer Joachim Lykke Andersen asked a question about this on StackOverflow, and then proceeded to find a pretty nice solution to it himself, which he has now blogged.  His solution relies on handling the VS OnBuildBegin event.  So basically, you just do a one time step, and then you don’t need to worry about it.  I won’t repeat all the details here, so get them on his post.

He also discusses the possibility off turning this into an Addin, which would be yet cooler.  And maybe with some convincing he will, so add a comment to his post :)

 

POLL: should we kill the AlwaysKeepTemplateDirty flag?

Given that this is a cleaner solution to this issue, I’m thinking of removing the AlwaysKeepTemplateDirty logic.  At the very least, I could turn it off by default in the T4MVC.settings.t4 (currently it’s on by default).  But in the end, it’s a hack and I wouldn’t mind getting rid of it altogether.

Would anyone object to this, or have concerns about this new approach?  Just let me know in the comments…

Ms-PL Source Release for System.Web.Mvc 2

Hot on the heels of the release of ASP.NET MVC 2 yesterday, I’m happy to announce that we are releasing the source code to ASP.NET MVC 2 under the Ms-PL license, an OSI approved Open Source license.

This continues the trend from nearly a year ago when we released ASP.NET MVC 1.0 under the Ms-PL. You can read my blog post there to learn more about the hard work that goes into such releases.

While I’m one who loves lawyer jokes, I do appreciate the work that they do (one of my best friends is a lawyer) and am grateful for the hard work our legal team put in to make this happen again.

Get the source!

To grab the source code, visit the ASP.NET MVC 2 RTM Download Details page and look for the file named mvc2-ms-pl.zip.

What’s next?

This time around, we’re not planning to stop with just the source code for System.Web.Mvc.dll. There’s a bit more source I would like to release under the Ms-PL which should hopefully be coming soon if I can get the ducks to line in a row (who knew releasing code required working with ducks?!).

DevExpress is a Platinum Sponsor of Austin Code Camp 2010

dev-exp-logo-with-slogan-350

Developer Express Inc. develops Feature-Complete Components for ASP.Net and Winforms, Reporting Tools, IDE Add-ins, and Business Application Frameworks for Visual Studio.

Information at www.devexpress.com

On behalf of the Austin .Net Users Group (ADNUG) and every attendee of Code Camp 2010, we would like to thank DevExpress for your contribution to Code Camp 2010. This event is funded by your contribution and would not be possible without your support of the local technology community:

Our Sincerest Thanks,

Austin Code Camp 2010 Committee

 

To Attend, Speak, Volunteer, or Sponsor the Austin Code Camp go to http://Codecamp.Adnug.org

Kick It on DotNetKicks.com

ASP.NET MVC 2 Released!

It’s that time of year again when the sakura (cherry blossoms) bloom and allergies kick into high gear. When the drive home is no longer shrouded in darkness and when the ASP.NET team releases Software!

sakuraEarlier today we released the RTM of ASP.NET MVC 2 for Visual Studio 2008 SP1. See Scott Guthrie’s announcement about it. For download and install options, visit the ASP.NET MVC Download Page.

Here are a few helpful resources to help you learn more about this release.

My team and I are excited about this release as it adds a lot of great new functionality for those building web applications with ASP.NET MVC. As with ASP.NET MVC 1.0, the community (yes, that’s you people!) were heavily involved in the making of this product via multiple preview releases. So thank you!

What about Visual Studio 2010?

Keep in mind that this release includes project templates for Visual Studio 2008. Visual Studio 2010 RTM will be released fairly soon and that will contain project templates and runtime for ASP.NET MVC 2 RTM in the box.

If you have Visual Studio 2010 RC installed, you’ll find that the installer for ASP.NET MVC 2 RTM is blocked just as it was for ASP.NET MVC 2 RC 2.

To remedy the situation, you just need to uninstall the ASP.NET MVC 2 runtime first, and then run the ASP.NET MVC 2 RTM installer.

I’ve outlined the steps in more detail in a previous blog post describing how to install MVC 2 RC 2 on a machine with Visual Studio 2010 RC. These same steps apply, but switch “RC 2” with “RTM” of course. :)

Again, sorry for the inconvenience. Once Visual Studio 2010 RTM ships, this will all just work.

Source Code! Source Code! Source Code!

As always, the source code, along with our Futures library, is available on CodePlex. For those looking for the Ms-PL package, we will be releasing the source code for System.Web.Mvc.dll very soon.

What’s Next?

I’m glad you asked. While we’ve been very busy getting this release ready, preparing for Mix 10, closing down on ASP.NET 4 and Visual Studio 2010, we’ve still found time to start preliminary planning for ASP.NET MVC 3.

It’s very early and nothing is written in stone yet (of course not, it’d be written in C#), but you can read our rough roadmap that outlines some of the ideas we have for the next version.

ASP.NET MVC 2 Released

ASP.NET MVC 2 is out. This means, it's released . It's final. Use it. Love it. You can download it directly , or install it (and whatever else you like) with the Web Platform Installer: ScottGu has many details in his post . There's lots of resources to check out: What's new in ASP.NET MVC Whitepaper ASP.NET MVC 2 adds a bunch of new capabilities and features.  ScottGu has a blog series about some of the new features, and will be covering them in more depth in the weeks ahead.  Some of the new features and capabilities include: New Strongly Typed HTML Helpers Enhanced Model Validation support across both server and client Auto-Scaffold UI Helpers with Template Customization Support for splitting up large applications...(read more)

No silver domain modeling bullets

This past week, I attended a presentation on Object-Role Modeling (with the unfortunate acronym ORM) and its application to DDD modeling".  The talk itself was interesting, but more interesting were some of the questions from the audience.  The gist of the tool is to provide a better modeling tool for domain modeling than traditional ERM tools or UML class diagrams.  ORM is a tool for fact-based analysis of informational models, information being data plus semantics.  I’m not an ORM expert, but there are plenty of resources on the web.

One of the outputs of this tool could be a complete database, with all constraints, relationships, tables, columns and whatnot built and enforced.  However, the speaker, Josh Arnold, mentioned repeatedly that it was not a good idea to do so, or at least it doesn’t scale at all.  It could be used as a starting point, but that’s about it.

Several times at the end of the talk, the question came up, “can I use this to generate my domain model” or “database”.  Tool-generated applications are a lofty, but extremely flawed goal.  Code generation is interesting as a one-time, one-way affair.  But beyond that, code generation does not work.  We’ve seen it time and time again.  Even though the tools get better, the underlying invalid assumption does not change.

The fundamental problem is that visual code design tools can never and will never be as expressive, flexible and powerful as actual code.  There will always be a mismatch here, and it is a fool’s errand to try to build anything more.  Instead, the ORM tool looked quite useful as a modeling tool for generating conversation and validating assumptions about their domain, rather than a domain model builder.

Ultimately, the only validation that our domain is correct is the working code.  There is no silver bullet for writing code, as there is always some level of complexity in our applications that requires customization.  And there’s nothing that codegen tools hate more than modification of the generated code  However, I’m open to the idea that I’m wrong here, and I would love to be shown otherwise.

Kick It on DotNetKicks.com

Migrating ASP.NET MVC 1.0 applications to ASP.NET MVC 2 RTM

ASP.NET MVC 2 RTM has just been released! More info on ScottGu's blog.

I have updated the MVC App Converter to convert projects from ASP.NET MVC 1.0 to ASP.NET MVC 2 RTM.

This should be last the last major change to the MVC App Converter that I released previews of in the past several months.

MVC App Converter screen shot

Download

The app is a single executable: Download MvcAppConverter-MVC2RTM.zip (255 KB).

Usage

The only requirement for this tool is that you have .NET Framework 3.5 SP1 on the machine. You do not need to have Visual Studio or ASP.NET MVC installed (unless you want to open your project!). Even though the tool performs an automatic backup of your solution it is recommended that you perform a manual backup of your solution as well.

  • To convert an ASP.NET MVC 1.0 project built with Visual Studio 2008 to an ASP.NET MVC 2 project in Visual Studio 2008 perform these steps:
    • Launch the converter
    • Select the solution
    • Click the “Convert” button
  • To convert an ASP.NET MVC 1.0 project built with Visual Studio 2008 to an ASP.NET MVC 2 project in Visual Studio 2010:
    • Wait until Visual Studio 2010 is released (next month!) and it will have a built-in version of this tool that will run automatically when you open an ASP.NET MVC 1.0 project
    • Perform the above steps, then open the project in Visual Studio 2010 and it will perform the remaining conversion steps

What it can do

  • Open up ASP.NET MVC 1.0 projects from Visual Studio 2008 (no other versions of ASP.NET MVC or Visual Studio are supported)
  • Create a full backup of your solution’s folder
  • For every VB or C# project that has a reference to System.Web.Mvc.dll it will (this includes ASP.NET MVC web application projects as well as ASP.NET MVC test projects):
    • Update references to ASP.NET MVC 2
    • Add a reference to System.ComponentModel.DataAnnotations 3.5 (if not already present)
  • For every VB or C# ASP.NET MVC Web Application it will:
    • Change the project type to an ASP.NET MVC 2 project
    • Update the root ~/web.config references to ASP.NET MVC 2
    • Update the root ~/web.config to have a binding redirect from ASP.NET MVC 1.0 to ASP.NET MVC 2
    • Update the ~/Views/web.config references to ASP.NET MVC 2
    • Add or update the JavaScript files (add jQuery, add jQuery.Validate, add Microsoft AJAX, add/update Microsoft MVC AJAX, add Microsoft MVC Validation adapter)
  • Unknown project types or project types that have nothing to do with ASP.NET MVC will not be updated

What it can’t do

  • It cannot convert projects directly to Visual Studio 2010 or to .NET Framework 4.
  • It can have issues if your solution contains projects that are not located under the solution directory.
  • If you are using a source control system it might have problems overwriting files. It is recommended that before converting you check out all files from the source control system.
  • It cannot change code in the application that might need to be changed due to breaking changes between ASP.NET MVC 1.0 and ASP.NET MVC 2.

Feedback, Please!

If you need to convert a project to ASP.NET MVC 2 please try out this application and hopefully you’re good to go. If you spot any bugs or features that don’t work leave a comment here and I will try to address these issues in an updated release.

Strengthening your domain: Encapsulated collections

Previous posts in this series:

One of the common themes throughout the DDD book is that much of the nuts and bolts of structural domain-driven design is just plain good use of object-oriented programming.  This is certainly true, but DDD adds some direction to OOP, along with roles, stereotypes and patterns.  Much of the direction for building entities at the class level can, and should, come from test-driven development.  TDD is a great tool for building OO systems, as we incrementally build our design with only the behavior that is needed to pass the test.  Our big challenge then is to write good tests.

To fully harness TDD, we need to be highly attuned to the design that comes out of our tests.  For example, suppose we have our traditional Customer and Order objects.  In our world, an Order has a Customer, and a Customer can have many Orders.  We have this directionality because we can navigate this relationship from both directions in our application.  In the last post, we worked to satisfy invariants to prevent an unsupported and nonsensical state for our objects.

We can start with a fairly simple test:

[Test]
public void Should_add_the_order_to_the_customers_order_lists_when_an_order_is_created()
{
    var customer = new Customer();
    var order = new Order(customer);

    customer.Orders.ShouldContain(order);
}

At first, this test does not compile, as Customer does not yet contain an Orders member.  To make this test compile (and subsequently fail), we add an Orders list to Customer:

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Province { get; set; }
    public List<Order> Orders { get; set; }

    public string GetFullName()
    {
        return LastName + ", " + FirstName;
    }
}

With the Orders now exposed on Customer, we can make our test pass from the Order constructor:

public class Order
{
    public Order(Customer customer)
    {
        Customer = customer;
        customer.Orders.Add(this);
    }

And all is well in our development world, right?  Not quite.  This design exposes quite a bit of functionality that I don’t think our domain experts need, or want.  The design above allows some very interesting and very wrong scenarios:

[Test]
public void Not_supported_situations()
{
    // Removing orders?
    var customer1 = new Customer();
    var order1 = new Order(customer1);

    customer1.Orders.Remove(order1);

    // Clearing orders?
    var customer2 = new Customer();
    var order2 = new Order(customer1);

    customer2.Orders.Clear();

    // Duplicate orders?
    var customer3 = new Customer();
    var customer4 = new Customer();
    var order3 = new Order(customer3);

    customer4.Orders.Add(order3);
}

With the API I just created, I allow a number of rather bizarre scenarios, most of which make absolutely no sense to the domain experts:

  • Clearing orders
  • Removing orders
  • Adding an order from one customer to another
  • Inserting orders
  • Re-arranging orders
  • Adding an order without the Order’s Customer property being correct

This is where we have to be a little more judicious in the API we expose for our system.  All of these scenarios are possible in the API we created, but now we have some confusion on whether we should support these scenarios or not.  If I’m working in a similar area of the system, and I see that I can do a Customer.Orders.Remove operation, it’s not immediately clear that this is a scenario not actually coded for.  Worse, I don’t have the ability to correctly handle these situations if the collection is exposed directly.

Suppose I want to clear a Customer’s Orders.  It logically follows that each Order’s Customer property would be null at that point.  But I can’t hook in easily to the List<T> methods to handle these operations.  Instead of exposing the collection directly, I will expose only those operations which I support through my domain.

Moving towards intention-revealing interfaces

Let’s fix the Customer object first.  It exposes a List<T> directly, and allows wholesale replacement of that collection.  This is the complete antithesis of intention-revealing interfaces.  I will now only expose the sequence of Orders on Customer:

public class Customer
{
    private readonly IList<Order> _orders = new List<Order>();

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Province { get; set; }
    public IEnumerable<Order> Orders { get { return _orders; } }

    public string GetFullName()
    {
        return LastName + ", " + FirstName;
    }
}

This interface explicitly tells users of Customer two things:

  • Orders are readonly, and cannot be modified through this aggregate
  • Adding orders are done somewhere else

I now have the issue of the Order constructor needing to add itself to the Customer’s Order collection.  I want to do this:

public class Order
{
    public Order(Customer customer)
    {
        Customer = customer;
        customer.AddOrder(this);
    }

Instead of exposing the Orders collection directly, I work through a specific method to add an order.  But, I don’t want that AddOrder available everywhere, I want to only support the enforcement of the Order-Customer relationship through this explicitly defined interface.  I’ll do this by exposing an AddOrder method, but exposing it as internal:

public class Customer
{
    private readonly IList<Order> _orders = new List<Order>();

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Province { get; set; }
    public IEnumerable<Order> Orders { get { return _orders; } }

    internal void AddOrder(Order order)
    {
        _orders.Add(order);
    }

There are many different ways I could enforce this relationship, from exposing an AddOrder method publicly on Customer or through the approach above.  But either way, I’m moving towards an intention-revealing interface, and only exposing the operations I intend to support through my application.  Additionally, I’m ensuring that all invariants of my aggregates are satisfied at the completion of the Create Order operation.  When I create an Order, the domain model takes care of the relationship between Customer and Order without any additional manipulation.

If I publicly expose a collection class, I’m opening the doors for confusion and future bugs as I’ve now allowed my system to tinker with the implementation details of the relationship.  It’s my belief that the API of my domain model should explicitly support the operations needed to fulfill the needs of the application and interaction of the UI, but nothing more.

Kick It on DotNetKicks.com

Supercharging ASP.NET MVC with MvcContrib (article)

CoDE Magazine has published a new article from me on MvcContrib.  Here is an excerpt:

Hot on the heels of the groundbreaking release of ASP.NET MVC CTP 1 in December of 2007, an open source project called MvcContrib came to life. MvcContrib has enjoyed tens of thousands of downloads since it started in December of 2007. In this article, I will explain MvcContrib; it’s major components, how to use it, and how to get involved in its continued development.

MvcContrib from 30,000 Feet

MvcContrib is a .NET 3.5 SP1 library that provides extensions for use with Microsoft’s ASP.NET MVC Framework. MvcContrib does not provide replacements for parts of ASP.NET MVC.

 

Click here for the full CoDe Magazine article.

T4MVC 2.6.13: now officially in MvcContrib, with a few new features

To get the latest build of T4MVC:

Go to MvcContrib T4MVC page on CodePlex

 

A few weeks back, we announced (mostly on Twitter) that T4MVC was moving into the MvcContrib Codeplex project.  I didn’t say much about it at the time because there wasn’t a whole lot to say yet, in the sense that the move had not actually happened.  MvcContrib was transitioning from github to Mercurial, and since I wasn’t familiar with either one, I figured I’d wait for that and only have to learn Mercurial.

So to make it short, all of this has finally happen, and we can now say that T4MVC is officially part of MvcContrib!  Many thanks to Eric Hexter and Jeremy Skinner for helping make this possible.

 

So what difference does it make for it to be in MvcContrib?

The download and documentation pages moved to into MvcContrib, but that in itself is not very interesting.  The major difference is that it will now be much easier for anyone to contribute changes, given that the project is completely open source.  Previously, people were sending me suggestions by email, and the whole process was very ad hoc.

Now you can contribute changes the same way you would for the rest of MvcContrib.  Please check out this new instruction page that Jeremy just put together.  If you’ve used Mercurial before, you’ll barely need to read it.  If you have not, then you’ll need to learn the basics.  I found this site by Joel Spolsky to be a great intro.

More specifically, all the files that relate to T4MVC are under /src/T4MVC in the repository.  Note that right now, they only exist in my fork of the repository, but in a few days they’ll propagate to main.  Note that most of the files there are really just part of the test app that T4MVC is in for unit testing.  When it comes down to it, T4MVC is still just two plain text files (T4MVC.tt and T4MVC.settings.t4), and they’re under /src/T4MVC/T4MVCHostMvcApp/T4MVC Files/.  There is nothing that really needs to be built per say other than to run the tests.

 

What’s new in 2.6.13

In addition to the MvcContrib move, T4MVC 2.6.13 brings in a few new features.

Support to include an optional timestamp query string in the static file links

This idea came from Wayne Brantley.  From T4MVC.settings.t4:

// If true, links to static files include a query string containing the file's last change time. This way,
// when the static file changes, the link changes and guarantees that the client will re-request the resource.
// e.g. when true, the link looks like: "/Content/nerd.jpg?2009-09-04T12:25:48"
const bool AddTimestampToStaticLinks = false;

By default, this is turned off, so switch the flag if you want to use it.

 

Added support to recognize the [Bind(Prefix=”…”)] attribute

This one was suggested by Kris Penner.  Suppose you have an action that looks like this:

public virtual ActionResult ActionWithBindPrefixAttribute([Bind(Prefix = "newParamName")] string fieldName) {
    ...
}

What this means is that this parameter needs to get sent as ‘newParamName’ instead of ‘fieldName’ in the route values.  Previously, T4MVC was ignoring this and basically doing the wrong thing.  Now, calling MVC.MyController.ActionWithBindPrefixAttribute("Hello") will correctly generate a route value that has newParamName=”Hello”.

 

New way to easily add all the query string values to the route

Another Wayne Brantley Idea (he keeps me busy! :)).  Suppose you want to add all the current query string values to the route values produced by T4MVC.  You can now use a new AddRouteValues() overload that takes a NameValueCollection.  e.g.

RedirectToAction(MVC.Home.MyAction().AddRouteValues(Request.QueryString));
This adds to the existing set of AddRouteValue/AddRouteValues fluent APIs to make it easier to deal with all kind different situations.

 

New MapRoute overload that supports constraints

This was just a missing overload that’s needed when you use T4MVC in your route and happen to also need some constraints.  Here is the overload:

public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, object constraints);

 

Removed some VS2010 Beta 2 specific logic

There was some transitional logic that only made sense in beta 2, so I yanked it since everyone should be using VS2010 RC or later now.  Note that T4MVC still works fine on VS2008 SP1, and works with both MVC 1 and MVC 2.  It’s only support for the old 2010 Beta 2 that’s being removed to clean things up.