Patterns & Practices
From the point of view of the user of the container, he doesn't have to do anything at all. He just creates classes as usual:
public class EditCustomersPresenter
{
public EditCustomersPresenter(IEditCustomersView view, ICustomerRepository repository)
{
this.view = view;
this.repository = repository;
view.Presenter = this;
}
...
}
Container configuration is done through lambdas that specify which object to construct for the registered type. For the view used by this presenter (an EditCustomersView form), it would look like:
var container = new Container();
container.Register<IEditCustomersView>(
c => new EditCustomersView());
In this sense, you can think of Funq as a glorified dictionary of delegates to instantiate objects (it does a bit more than that, though). In the above case, the class we're constructing doesn't need any dependencies. If it did, such as the presenter above, you can use the "c" argument to the lambda, which is the container itself, which you can use to express that you'll need to resolve the dependencies to pass on:
container.Register(
c => new EditCustomersPresenter(
c.Resolve<IEditCustomersView>(),
c.Resolve<ICustomerRepository>()));
Note that because this is a lambda/delegate, it won't actually be executed until the presenter is needed. Moreover, note how the type to register can be omitted if it matches the created object type (i.e. you don't want to register the presenter as an interface).
Because this is configuration, you can also pass configuration data on your registrations:
container.Register<ICustomerRepository>(
c => new CustomerRepository("[CONNECTION STRING TO DB / AppSetting / etc]"));
Moreover, the object itself can expose properties that affect its behavior, which can also be initialized at this point using C# 3 object initializer syntax:
container.Register<ICustomerRepository>(
c => new CustomerRepository("...") { IsAudited = true });
More lambda "magic" makes it possible to arbitrarily initialize the object when it's constructed, by using the InitializedBy fluent method:
container
.Register<ICustomerRepository>(
c => new MemoryCustomerRepository())
.InitializedBy((c, r) =>
{
// Initialize with some fake data.
r.Create(new Customer { FirstName = "Joe", LastName = "Doe" });
r.Create(new Customer { FirstName = "Sarah", LastName = "Smith" });
r.Create(new Customer { FirstName = "Mary", LastName = "Brown" });
});
The InitializedBy method receives a lambda with two arguments: the first is again the container, in case we need to further resolve dependencies, and the second is the instance created by the first delegate (at the time it was needed), typed to the registration type (ICustomerRepository in this case, or the constructed instance type if you omitted it) passed on so that you can call methods, set properties, etc. on it.
Lazy resolve
Let's say a service needs to be able to create/resolve a dependency on-demand. Typically, you'd create a factory for that, and have the factory instantiate the object through the container. Funq provides built-in support for this via factory functions as a built-in concept.
If you had a controller that instantiated use cases as needed, you wouldn't want to create all the possible use case classes up-front. So let's say you have a registered use case class:
container.Register<IUseCase>("AddCustomer", c => new AddCustomerUseCase());
Note that instances can be named so that you can register many under the same interface.
The controller class would need to run this use case at some point. It would have a constructor dependency not the actual instance, but on a resolver delegate to it:
public class CustomersController
{
public CustomersController(Func<IUseCase> addCustomerResolver, ...)
{
...
}
public void AddCustomer()
{
// invoke the function, which would create the use case as registered.
IUseCase useCase = addCustomerResolver();
useCase.Run();
}
}
You'd register the controller slightly different, by lazy resolving the use case dependency
container.Register(
c => new CustomersController(
c.LazyResolve<IUseCase>("AddCustomer"))
The LazyResolve method works (and provides same overloads) just like the Resolve, but it returns Func delegates instead, so that the actual invocation to Resolve is delayed until you execute the delegate. This is very useful in many scenarios, and avoids many one-line factories.
Passing constructor arguments
Another common scenario we wanted to support without sacrificing performance was to allow passing constructor arguments to these registered "factories". Let's say you have a Queue object that needs the queue name:
If you have the following queue class:
public class Queue : IQueue
{
public Queue (string queueName)
{
...
}
}
You'd register it like so:
container.Register<IQueue, string>(
(c, name) => new Queue(name));
Note how you specify in addition to the service type, the type of the arguments that it requires. In order to resolve it, you must therefore pass a string for the invocation:
var queueOut = container.Resolve<IQueue, string>("outgoing");
This would allow you to configure something like a notifications service with two queues with different names:
public class NotificationService : INotificationService
{
public NotificationService(IQueue input, IQueue output)
{
...
}
And its corresponding registration would be:
container.Register<INotificationService>(
c => new NotificationService(
c.Resolve<IQueue, string>("in"),
c.Resolve<IQueue, string>("out")
);
This also works for lazy resolution, so if the service creates the queues on-demand, it could be defined as follows:
public class NotificationService : INotificationService
{
public NotificationService(Func<IQueue, string> queueResolver)
{
...
}
public void Reply(string message, ...)
{
using (var queue = queueResolver("out"))
queue.Enqueue(message);
}
Note that the service invokes the resolver passing the queue name. Registration would be slightly different now:
container.Register<INotificationService>(
c => new NotificationService(c.LazyResolve<IQueue, string>())
);
Passing arguments can also be done at registration time for dependencies. Imagine you introduce a IQueueFactory service that must receive a queue name in its constructor so that its caller can create multiple instances of the same queue object as needed, without knowing the queue name at all. A notification service would use such a factory as follows:
IQueueFactory factory;
public NotificationService(IQueueFactory factory)
{
this.factory = factory;
}
public void Send(string text)
{
using (var queue = factory.CreateQueue())
{
queue.Enqueue(text);
}
}
The service doesn't know which particular queue it's going to send the message to. And (for whatever reason) it needs to create a new queue whenever it needs it. The registration for such an object, would simply be:
container.Register<IQueueFactory, string>(
(c, name) => new QueueFactory(name));
Note how the registration overload we're using specifies that in addition to the service type, we'll need a string argument to construct the object. Now it's time to register the notification service, which (say) we have two of: input and output notifications
container.Register("outgoing",
c => new NotificationService(c.Resolve<IQueueFactory, string>("out-queue")));
container.Register("incoming",
c => new NotificationService(c.Resolve<IQueueFactory, string>("in-queue")));
What's happening here is that we're registering the same service twice with different names, and resolving the queue factory dependency passing the desired queue name that will be received by its implementation. This way, we have externalized the dependency on this knowledge from the notification service.
The same effect (of "fixing" a lambda parameter to a given value) can be achieved by just currying the function returned from LazyResolve :)
If you follow my blog, you probably heard about Funq, and maybe you even watched the screencasts I did about it while developing it (yeah, I'm missing a bunch of new ones!).
When we started working on a rev for the original Mobile Client Software Factory v1 for patterns & practices, we had a list of top-priority issues and feature requests expressed by the community and the advisory board. Very high on the list was *removal* of the Composite UI Application Block (CAB) from the blocks, as its performance impact was too great for mobile apps.
Despite all my efforts to make CAB more performant (including compile-time codegen a-la sgen of the injection policies), I just couldn't make it fly. It was simply not designed for a constrained execution environment where things like allocated bytes and JIT compilation DOES matter.
Yet, we didn't want to just rip-off CAB and leave nothing to replace it. Designing an application in a loosely coupled way and enabling testability are important goals that we wanted to encourage in the mobile world. So I decided to start from scratch on the simplest possible DI container we could give mobile developers that could add sufficient value to their architectures without compromising application cold boot speed or general runtime performance.
The culmination of that effort is a very simple container (I claim anyone can crack open the source code and understand it quite easily ;)) that outperforms every other DI container on the market by orders of magnitude. I named the new Mobile Application Blocks (MAB) DI framework ContainerModel. p&p already has a desktop/silverlight offering in the space with Unity, so with their authorization, I forked (but keep 100% in sync) the project into Funq, which provides the desktop and silverlight binaries and source. So, MAB ContainerModel == Funq. It may be that the latter adds features that only apply to the desktop and/or silverlight (i.e. ASP.NET MVC and WCF integration, etc.), but the core will always remain in sync.
The performance results for the CF version are:
Here you can see how bad ObjectBuilder v1 (the backbone of CAB) was, even at a generous (estimated average) 7x performance gain via compile-time codegen, resulting in a 133x overhead! (without the obgen compile-time tool, it would be ~900x :S).
In comparison, the new ContainerModel is a modest 12x slower than no DI at all, and still orders of magnitude faster than a quick port to CF of both Autofac and Unity.
On the desktop, numbers are also equally encouraging:
This shows only the top 3 performing containers, as including others such as Windsor ruins the graph (it's 6x slower than Autofac, about 80x slower than Funq).
As I said, key performance counters you typically don't measure on the desktop are of critical importance on the CF. So I developed the container while carefully watching the impact on those. Here are the results and comparison:
As you can see, Unity does significantly better than the original ObjectBuilder, but it was still not enough for CF. The new ContainerModel overhead is barely noticeable across all areas, with consistently low impact.
To be honest, the comparison on the CF is unfair to the other frameworks, because none of them were designed nor optimized for use on mobile devices. I just ported enough of the code to get them to compile and run.
Over the next few posts, I'll explain more about its design and features. Stay tunned!
Last week I presented this topic in Zurich, based on p&p ObjectBuilder.
It's amazing how much interest people show around this topic, yet there
is so little available on the web about ObjectBuilder.
The
project has been open sourced for a while now, but the lack of good
documentation and a full DI container hindered its adoption. First
thing I hear on these conferences is that it's too low-level, and that
higher level APIs are needed.
I believe that's what will happen in the short-term. ObjectBuilder is a
very good tool to apply simple dependency injection and object
composition functionality in your app, without taking huge
dependencies. For the most part, you can make it work even without
using custom attributes and the like.
You can get the slides (PowerPoint 2007), and download the sample project that compares the usage against standard hardcoded dependencies and even Pico and Spring.
I've just now noticed that Ron Jacobs has uploaded our talk in TechEd Barcelona back last November.
It was supposed to be about designing orientation aware and DPI aware mobile applications using the Mobile Client Software Factory and its Orientation Aware Control Block (see http://orientationaware.net/ ;)), but ended up being about other parts of the factory, about ObjectBuilder and optimizations I did to avoid runtime reflection to inject dependencies, CAB, mobile development in general, etc. It was a fun interview :).
Go ahead and download it!
Software factories is an elusive concept nowadays. In this article, I will try to help you understand which technologies can be used today to build production-quality factories and the reasons for the perceived inconsistency in the tools and the vision on Microsoft's part.
None of what follows is speculation: I've been a main developer on one of the two core technologies that realize today' software factories (patterns & practices Guidance Automation Toolkit or GAT), and as such I've been in close contact with the teams and architects building the technologies I will explain here (including Jack Greenfield, Wojtek Kozaczynski, Mauro Regio and others). Also, my company is a leader in software factory development, providing most of the people that build the factories coming out of the most active practitioner in the area today: the Microsoft patterns & practices group. We also have several customers around the world that we helped reap the amazing productivity boost that today's factory tools can bring.
First and foremost: this article is NOT about the grand vision (still underway, rest assured, but nevertheless in the realm of the future) outlined in The Book: Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools by Jack Greenfield, Keith Short et all. I will talk about technologies that are ready for production today. This also means that the strict concept itself of a SF outlined in the book needs to relaxed for what's currently possible with the available tools. You can think of today's factories as infants that will grow with features as times goes by and the end-to-end SF vision becomes a reality. That doesn't prevent the "infant" from giving you a big boost in terms of productivity and software quality.
You can build SF today by using a combination of the following two tools:
-
DSL Tools: or Domain Specific Language Tools. This is a toolkit for creating VS-integrated graphical notations for a given model that you basically make up. It allows you to construct a custom-tailored designer for a model for your problem domain.
-
GAT/GAX: or Guidance Automation Toolkit/Extensions. This is a toolkit for extending VS with solution, project and item templates, code snippets and so-called recipes (or developer use cases) exposed as context menus within VS, that guide the developer in completing a complex task.
The problem is that integrating the two is not a trivial task. Why you may ask? Aren't they both coming from Microsoft? And how does GAT/GAX fit in the SF vision? After all it's not even mentioned in The Book!
Glad you asked ;). In order to understand this "mess", and figure out how to make it work for you, you need to understand a little bit of the background behind the two technologies. The DSL Tools is basically the first step in the road to realizing the full SF vision outlined in The Book. Hence, if you try to build a real-world factory just using DSLs, you will find it fairly incomplete and not supporting typical scenarios such as providing an initial solution structure where you will put your DSLs, etc. The missing features, though, are most probably those that will come (or become unnecessary) as the full vision is implemented. In the meantime, it feels lacking.
On the other hand, Microsoft patterns & practices (p&p) is NOT about building a compelling but somewhat distant feature, but about solving customers' problems today. p&p follows a process called "Customer Connected Engineering", which means customers get to influence what we do. Delivering guidance on how to best use the platform has been p&p traditional focus, but as guidance became more and more complex, thicker books and more complex libraries (think CAB and EntLib) just didn't cut it anymore. Customers were not getting the guidance in an easy to consume way. Hence, we set out to find a way to bring the guidance into Visual Studio, in a way that was easy to author (not only for p&p but for other companies delivering guidance internally) and contextual. The readily available VS extensibility mechanisms (add-ins and VSIP packages) did not satisfy either requirement, so we built our own framework on top of VSIP to allow for easier extensibility. And GAX was born. As the name implies, it's a mechanism for automating the guidance that you would have to otherwise perform manually by following a book's instructions.
You may notice that p&p software factories do not contain DSLs. This is in part because the goals of p&p SF are somewhat different than The Book SF. Their main purpose is to guide the developer through the best practices for implementing a given solution. In the end, it's the developer himself who implements the solution. It just so happens that he does so much faster and in a predictable way because he uses automated guidance within VS that generates code, unfolds boilerplate projects and solutions, provides code snippets, etc.
Given the different origins and goals of the two technologies, it may seem that they are hopelessly irreconcilable. Fortunately, that's not necessarily the case, and there are many ways in which they can be integrated. My partner Victor Garcia Aprea and Mauro Regio have published an article on MSDN about integration scenarios that include integrating the two.
A number of integration points are particularly critical:
- An initial solution structure is generally required: this can be done with GAX.
- Typically at a specific location in the solution, a domain model/designer could be added to design some area of the application (i.e. a business entities domain model, that generates business entities + data transfer objects + data access layer code + SQL files with stored procs for the DB). This needs to be done with a combination of DSL and GAX if you want the DSL to only be available at a specific location in the solution. (remember, GAX is about context)
- With the DSL in place, you may want to generate multiple code files (as in the case of the business entities model I mentioned above), maybe even in different projects, and maybe you even need to generate the projects themselves. Again, DSL tools alone is not enough. By default, it will do two things that are pretty bad for a real-world factory:
- The code (a T4 template) that transforms the domain model in a designer into actual code for your project is expected to live in the same project as the domain model file. You are given a custom tool that runs the transformation, and a solution explorer toolbar icon to run all the transformations in the solution/project ("Transform All Templates"). What kind of guidance are you giving your developers if they can modify it at will just by modifying the T4 template that generates their code? It's more like giving them an example that they can tweak, and typically you don't want your developers modifying the templates for code generation that your architects together with your senior devs have created to ensure quality code.
- Each T4 template results in exactly one big file with the output of running the codegen against the domain model. If your model designs business entities, you will end up with a huge file with all the entities in the model. Generally not a good idea, and certainly goes against the typical .NET coding practice of using one file per class.
And it will not do the other two things that you need: generate new projects, and generate files that target multiple projects. You can supplement the DSL with GAX in order to achieve all of this. Achieving the above two goals requires deep understanding of how both technologies work at a very granular level, though, but it's definitely possible (more on this later).
- You may want to launch recipes/execute actions from specific shapes in the domain model diagram (i.e. "Configure Security for Entity" or something like that, maybe even regenerate code for a specific model entity and not all of them). You can hook GAX recipes to the context menus on DSL diagrams pretty easily, and with some more work you can make it contextual enough to provide very granular visibility (i.e. only model entities that have property Foo = true).
Of course, the integration is not as seamless as it could have been. But I hope I shed some light on the current situation by sharing the background and how the two tools came to be. Moving forward, you can expect the experience to become much better, as the scenarios that led to GAT/GAX are integrated into the SF toolkit.
As you might have guessed, we (Clarius) have gone over each and every hop in this integration that you can possibly imagine. We have recently released a CTP of our Software Factories Toolkit, which helps integrate the two technologies, and which you can download for free.
I will be presenting some of the work I did for the patterns & practices Mobile Client Software Factory. It's been very fun to work on that project, and I plan to share as many tips & tricks on how the amazing Orientation Aware Control does it magic as attendeeds dare to ask ;-). After doing extensive research, I think this control is the only one (and with free source) that showcases some really advanced custom control development in general and in particular for the mobile platform. Session details:
DEV342 Designing Zero-Code Adaptive User Interfaces (UIs) for Windows Mobile
Daniel Cazzulino
- Fri Nov 10 10:45 - 12:00 Room 121
Designing mobile applications that support multiple form factors and resolutions is probably one of the most time-consuming and challenging aspects of mobile development. It is also the one that differs the most from traditional desktop application development, where simple docking or anchoring is usually enough. The Microsoft patterns & practices Mobile Client Software Factory comes to the rescue in this area, with the Orientation Aware Control, which allows designing and coding a single control with multiple layouts or skins, that are automatically applied at run-time (and design-time) according to the available form factor, resolution and orientation. You will learn not only how to apply it successfully to your projects, but also how it was implemented, directly from its core developer. With its outstanding Visual Studio forms and user control designer integration and zero-code adaptive UI behavior, the Orientation Aware Control is a must-have companion for any mobile developer. Being distributed in source form, it also makes for an excellent real-world example of advanced (mobile) custom control development techniques.
This will be a sample / source code driven session, with just a few slides to set the context.
As part of the
Mobile Client Software Factory I've been working on for the past few months,
we introduced the Orientation Aware Control (OAC). I blogged about it and showed it working. In this post I'll delve a little more on the process you go when building UIs for devices that must adapt to different resolutions and orientations.
I've already
hinted that the solution we implemented is based on the
Localization feature in .NET. So let's see how you go about using it.
First step is to add a new UserControl to your project, and changing the base class to inherit from the OrientationAwareControl class provided with the factory. After you do that, you will see something like the following:
New and modified properties:
- Localizable: as you can see from the property description from the above screenshot, this property is fixed to the True value. This is the proof that OAC uses the localization feature, and therefore this property cannot be changed.
- Orientation: this property can have the values Vertical | Horizontal, and corresponds to the Rotate command (both in context menu as command area in the properties window). It basically allows you to design different UI for the portrait and landscape orientations.
- Resolution: this property allows you to select one of the available resolutions. These resolutions can be the standard ones (VGA and QVGA standard or square), and will show up in a dropdown. More on how this list is populated and how to add custom resolutions later.
New commands: the commands, as is usual on custom control designers, are available either from the context menu of the control and in the command area in the properties window.
- Rotate: rotates the current layout, so that you can start designing the rotated layout. By default, the first time the control is rotated, controls bounds will be checked to see if they fit in the rotated control (height and width are switched). If they don't, they will be moved up and left until all controls fall within bounds of the container user control.
- Switch to Default Layout: by design, in VS2005 you can only add new components/controls through the designer if the current control/form is in the default culture. Because the OAC extends the localization infrastructure, the equivalent of the default culture is the default layout, meaning default culture + default resolution and vertical orientation. More on how to set which is the default resolution later on.
- The other three commands help in designing localized versions of the different resolutions. Basically, whenever you start with a new locale (say Spanish), the default layout is applied to the new resolution/orientation/culture, which is probably not optimum depending on which locale you are designing. For example, say you have QVGA-Spanish already designed, and now you want to design VGA-Spanish. The default culture layout will be applied and auto-scaled to give you a starting point. Well, in the localization case, you probably want to have all the labels and other text properties applied too, so that you don't have to translate everything again. Copy Text Properties is there for that purpose. You just switch back to the QVG-Spanish layout, click Copy Text Properties, and back in the VGA-Spanish, you click Paste Properties. All text properties will be set in all controls, saving you quite a bit of time. The same goes for the layout properties. If you already designed the layout for one, say, VGA-Horizontal resolution, and now you're localizing it, in every locale instead of re-locating all controls, you can simply Paste Properties after you run the Copy Layout Properties from the "source" layout (i.e. VGA-Horizontal, Default culture). Layout properties are basically location and size.
As you see, there's NO code whatesoever that you need to write to detect the current screen size and apply the appropriate resource. All is done automatically by the base Orientation Aware Control. In addition, and because we're reusing the localization feature in .NET, layouts are "inherited" across locales. Also, when no specific layout is found for the current resolution (i.e. a new device just came out), the default layout will automatically be applied.
How do resolutions work
I said above that the available resolutions are rendered as a dropdown you can pick from in the properties window. Here's how it looks:

Notice the description at the bottom of the window. This description is dynamic, and reflects the form factors that support the given resolution. So where is this information pulled from?
This is a pretty advanced control, which was very fun to develop. Turns out that there's an IPlatformInformation service exposed to device control designers, that allows you to list and retrieve form factors defined in Tools | Options | Device Tools | Form Factors options page in Visual Studio. This is how the page looks after you install the Windows Mobile 5.0 SDK:
At first, my control simply reused the FormFactor you already have in custom user controls:

That turned out to be a bad idea, as multiple form factors can have the same physical screen resolution, such as Phone VGA and VGA (both are 480x640). Hence, the OAC designer is hiding this property and providing an alternative one, the Resolution property. Basically it's populating the unique set of resolutions, and building the description dynamically to show which form factors defined in the VS options support the current value.
The OAC is fully integrated with the VS options dialog shown above. You can easily use the Save As button above to create a new form factor based on an existing one. After renaming it, you can click the Properties button and change its resolution. Once you're done, the control will automatically pick the new resolution (you may need to close and reopen the designer):

Note that in the VS options dialog you can also specify which is the default form factor, so that if your default target device is going to be, say, VGA, you don't need to change the resolution in every new control you create.
Stay tunned as I continue to explore the journey of building such a cool control, if I'm allowed to say so ;-). I have little doubt that this is the way to go for the .NET CF v3. We'll see...
And probably you know it is based on the super-cool Guidance Automation Extensions (GAX) and Toolkit (GAT). Read
Tom's post about what's new and improved in this release.
So you're hooked to this cool GuidanceAutomationToolkit. Now, say you have a cool recipe you'd like to place in an arbitrary context menu, such as the context menu over a Web Reference. In VS any menu is called a command bar. Now that particular context menu is not one of the command bars that GAT provides friendly aliases for:
Fortunately, GAT allows you to specify Guid and ID attributes that uniquely identify any menu in VS, so you can place your recipe anywhere you want. That's great, you say, but how in the world are you gonna know what values to use there? Turns out that until last week, I was fishing myself for those numbers in the VS SDK .ctc files (you don't even want to know what those are, believe me). Turns out that there's a much better and easy way, so I'd like to share it here.
The trick involves customizing the menu you want to put your recipe on, and then comparing the exported VS settings with a previous unmodified version, so you can tell the diff. The steps are:
- Go to Tools > Import and Export Settings...
- Select
Export selected Environment Settings option.
- From the tree, unckeck the root and then select only the
All Settings\General Settings\Menu and Command Bar Customizations node.
- Click Next. Ensure the message displayed says the export was successful and without errors (IMPORTANT!).
If you get an error, close and reopen VS, and try again without any solution opened. If you keep getting an error, I'm afraid you may need to reset your settings to the defaults (in the same dialog, select Reset all settings instead of Export...
- Open a project where you have a Web Reference. Select the Web Reference in the solution explorer
- Right-click on the toolbar and select
Customize
- On the
Toolbars tab, mark the Context Menus. At this point, a new toolbar with a number of dropdown menus should have appeared. Those are all the context menus currently available.
- Expand
Project and Solution Context Menus. You will see a number of entries. Now it's just a matter of finding the context menu you're looking for. In the case of the web reference, it's a little tricky (and that's why I chose this example) as the one you have to look for is named Folder (yuck!). But in general the names are pretty intuitive.
- Now we need to introduce a customization in this menu so that it shows up in the exported settings later on. So make a trivial change inside it, such as renaming one of its child items.
- Close the
Customize window.
- Repeat steps 2 to 4 to export the settings again, with a different file name this time.
The safest way to do the process above without risking your current settings is to use a virtual machine and reset all settings before doing the export. For the cleanest possible .settings file, it's also recommented that you reset to General Development profile.
Now open a diff program and compare the two files. You should look into the <UserCustomizations> node, and you should see a <modify> element with the change you made. In my case, I got:
<modify Cmd="{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}:0000045c"
CmdPri="03000000"
Group="{D309F791-903F-11D0-9EFC-00A0C911004F}:000002a3"
GroupPri="02000000"
Menu="{D309F791-903F-11D0-9EFC-00A0C911004F}:00000431"
Name="Updates Web Reference"/>
Note that I changed the name of the Server Explorer item to Server Explorers. You can then rollback by simply importing the original settings you exported. The important piece is in bold above: the Menu attribute. That value is the Guid and ID you're looking for! Keep in mind that the ID after the ":" is an hexadecimal value, so you have to convert it to an integer.
From the information above, I can now place a new recipe in the View menu just by specifying:
<CommandBar Guid="D309F791-903F-11D0-9EFC-00A0C911004F" ID="1073" />
Here's the proof ;-)
Now, the most interesting thing is that you don't have to do *anything* at all in order for that menu to be hidden whenever the associated recipe is not available (i.e. it's associated with an unbound recipe reference that specifies that it should only be enabled on certain targets, or it's a bound recipe associated with a particular solution element). In cases like the above, when you're already putting the recipe in a very specific context menu, that may not be such a compelling feature, but if you're placing your recipe in a common menu (like some of the main menus), it's a good feature to have. It makes for a less cluttered user experience.
The reality of mobile development (specially if you're creating a product) is not so different to that of web development: the clients that will be using the application may not be under your control, and they may support different sets of features and capabilities. In the ASP.NET world, this was solved by the set of mobile-enabled controls, that basically rendered different markup depending on the device. Even in ASP.NET v2.0, this solution (the so-called control adapters architecture) is still in its infancy and not fully completed in its integration with the "standard" controls.
In the mobile development world, the problem is not even in its infancy. Up to know, that is ;-).
In the devices world, the critical difference between clients is not on the platform (as in the web, where you have different browsers supporting different standards, etc.). When you decide to develop your application using .NET Compact Framework (CF), you're already filtering the range of devices to Windows-based (most probably Windows Mobile 5.0 if it's a brand new one) Pocket PCs or SmartPhones. In this scenario, your most challenging issue is how to support the different so-called form factors (or resolutions, such as VGA, QVGA) and screen orientations (can be landscape or portrait).
The Microsoft .NET Compact Framework (CF) 2.0 introduces some features that certainly help alleviate the problem, specifically in the WinForms area, where you can use the familiar docking and anchoring funcionality to have your controls automatically resize according to screen size. However, this falls short for most applications. For example, say you’re displaying a purchase order in a vertical QVGA screen (240x320). Most probably you have laid out the controls so that each value you want to show is displayed in a single “line”. Well, if the screen is rotated, you probably don't want to simply make your fields wider. That may be a waste of valuable space, and result in a poorer user experience by the requirement to constantly scroll the screen. In this case, it may actually be better to lay out controls differently, so that you can for example display two values per "line".
Of course, the logic of the user control/form (hereafter simply referred to as "control", which is even technically correct as the Form class inherits from Control too ;-)) is the same: the data binding, event wiring, the controller/presenter logic, etc. So in an ideal world the layouts would be sort of "skins" for the control, that are applied dynamically depending on the current device form factor and orientation.
If you think for a moment on the problem at hand, and how the ideal solution would look like, you may realize that the .NET Framework (and therefore the CF too) already provides a mechanism that allows applying "skins" to WinForms controls: localization. Making a form localizable allows you to completely re-arrange the layout for each supported language, including size, location, text, etc. Basically any property that has been "tagged" with [Localizable] can participate in this "skinning".
Good news is that the Mobile Client Software Factory (MC-SF) from p&p makes this ideal solution a reality with the introduction of a custom user control that you can use as the base class for yours. I've been working for the past few weeks on this feature, and I think it's an absolutely revolutionary simplification of the way you will author UIs for multiple devices. In future posts I will discuss its features and implementation, but in the meantime, here are a number of screenshots that should speak for themselves ;-)
In this picture you can see the new Rotate verb on the context menu of a derived control, and also the new dependent file TeamView.resources, which I'll explain in future posts and is the key to the multiple resources design. You can also see the new Orientation property in the Design category, as well as the Localizable property which is now read-only and forced to True. I already hinted that our solution leverages the localization features of .NET, and therefore relies on that property being True.
Here you can see that the horizontal layout for the very same control has a completely different design. The labels and textboxes are now on the right side, to take advantage of the extra space available in landscape mode, and to avoid unnecessary scrolling.
This is a screenshot of the emulator running the application with the orientation aware control. In a future post I will link to the download of this sample, so that you get to know the team behind the p&p Mobile Client Software Factory ;-) (that's what the data on the list is).
Finally, you can see that when the user rotates the screen, the control automatically re-applies the corresponding layout. Pretty cool, right? ;-) Stay tunned.
Today I presented a webcast on p&p ObjectBuilder (OB), the underpinning framework powering CAB and EntLib v2.0.
I'm afraid I tried to cover too much ground and the result was a pretty fast and maybe hard to follow session. I think it would have been much better to do an OB introduction webcast alone, and then another one on how to extend it. My apologies for that. I'll appreciate your feedback.
I showed some examples of how to use OB programmatically, as well as how to extend it. You can download the source, which is fairly big as it contains Pico.NET and Spring.NET in addition to OB itself. Also, you will see a side-by-side example of Fowler's MovieFinder example running in all three frameworks, so you can appreciate the differences.
As annouced a while back, patterns & practices is coming with guidance and tooling on how to best author applications for mobile devices (Pocket PCs), initially targetting the Windows Mobile 5.0.
I’m very excited to be part of this project, as it represents a new challenge in terms of a new platform, but where most of the same sound architectural principles that we been applying over the past years working with p&p still apply.
What’s more, as you already know from the latest p&p deliverables, we’ll continue to be very agile and responsive to community feedback. For that very reason, we have already started releasing weekly drops for you to take a look at! Go ahead and subscribe to the workspace, and don’t hessitate to send your comments through the message board. The entire team is listening.
In my next couple posts I’ll talk about a cool feature for the factory that we’ve been working on for the past couple weeks: the Dynamic Resolution Control. In short: author your single application, give your custom controls multiple alternative layouts for the various resolutions (i.e. QVGA horizontal, VGA vertical, VGA Square vertical, etc.), and have the control dynamically re-apply the layout when the user rotates the screen! Stay tunned. The user experience in VS is pretty cool, I think :)
These are roughly the things that you need to change in your current package:
- Search replace "50505" with "51206" in the entire solution. This is the changed assembly version number that appears in all your .vstemplates.
- Delete all references from all projects to Microsoft.Practices.* and re-add them pointing to the new version of the binaries.
- Search replace "igt" with "gax" (for XML and .vstemplate files)
- All T3 templates need to be updated to the T4 syntax shared with the DSL tools
- Search & replace: Microsoft.Practices.RecipeFramework.Library.Actions.T3Action, Microsoft.Practices.RecipeFramework.Library with Microsoft.Practices.RecipeFramework.VisualStudio.Library.Templates.TextTemplateAction, Microsoft.Practices.RecipeFramework.VisualStudio.Library
- DteHelper class now lives in the Microsoft.Practices.RecipeFramework.Library namespace and assembly.
- In .vstemplate files, you could previously specify initial state for your recipes with the following syntax:
<TemplateReference Name="Projects\ServiceAgent\ServiceAgent.vstemplate" Target="\ServiceAgents">
<XmlSerializableHashtable xmlns="http://schemas.microsoft.com/pag/igt-xmlhashtable" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Entries>
<Entry>
<Key xsi:type="xs:string">Key1</Key>
<Value xsi:type="xs:string">Value1</Value>
</Entry>
</Entries>
</XmlSerializableHashtable>
</InitialState>-->
</TemplateReference>
That has been replaced by the much simpler format:
<TemplateReference Name="Items\SerializableClass.vstemplate" Target="/" >
<InitialState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Entry>
<Key>SerializableField</Key>
<Value>Name</Value>
</Entry>
</InitialState>
</TemplateReference>
Of course, you can still use xsi:type just like the XmlSerializer does to get strongly typed initial values. You can put pretty much whatever you want there, as long as the value is compatible with the corresponding arguments defined for the recipe.
I think that's all, but let me know if you find anything that's missing or not working!
The Guidance Automation Extensions (GAX) and Toolkit (GAT) have been updated for Visual Studio 2005 RTM. As Tom describes it:
At long last, the Guidance Automation Toolkit (GAT) and Guidance Automation Extensions (GAX) have been updated for the final version of Visual Studio 2005. For those that came in late, GAT allows developers and architects to integrate guidance deliverables such as blocks, frameworks and patterns into the Visual Studio environment, using mechanisms such as templates, wizards and code generation. GAT is targeted at people authoring these "guidance packages", while GAX is the runtime component required by anyone consuming guidance packages. You'll be seeing quite a few p&p deliverables built using GAT (and hence requiring GAX) over the next year, so this would be a great time to get up to speed on this exciting technology.
Just as a quick list of things that GAX/GAT enables you to do, *very* easily:
- Create reusable actions that automate VS using either the DTE or the VSIP interfaces.
- Create rich argument collection strategies for use in wizards using .NET standard TypeConverter and UITypeEditor base classes. This also means that you get the built-in ones supported in your wizards for free!!
- Create automatic argument calculation strategies, that can determine (default) argument values from the environment (such as the opened solution, currently selected project properties, VS state, etc.)
- Declaratively design wizards using XML, by specifying the arguments that need to be collected, their .NET type and converters/editors to use to assist the user and validate the input, and even custom pages (a special kind of user control) for advanced input scenarios!
- Group the arguments used by the actions, the automatic argument collection strategies, the wizard to manually them from the user, and the set of actions to perform on the environment in so-called recipes.
- Easily associate recipes to item, project or solution templates, so that additional arguments can be collected for the VS template expansion and parameter replacement, as well as to execute actions after the unfold operation finishes.
- Easily expose those recipes as commands in main or context menus. Assign icons to them simply by pointing to an image file! (no more unmanaged VC++ resources for icons or those ugly .CTC files defining commands in VSIP!!!)
- Create code generation templates using a text templating language code-named T4 that is shared with the DSL Tools (similar in spirit to classic ASP, CodeSmith, NVelocity, etc.)
- Easily contextualize the recipes and templates so that they appear only for:
- A particular element in the solution (i.e. a specific project, item, solution folder, etc.)
- Elements that satisfy a given condition, coded easily in any .NET language (i.e. all XML files, XML files whose root element belongs to a given namespace, all C# projects that are class libraries and have a reference to Indigo, etc.)
- Easily create and package code snippets with your guidance
- Automatically create an MSI setup file to include all the above!
If the above list grabbed your interest, go and download GAX and GAT and start playing with it! Don't forget to ask your questions either on the MSDN forum or the GuidanceAutomation.net community site.
Read the following entry on how to upgrade from Beta2-based GAT packages and the new version.
Somehow I missed the link before. Go listen
Ron and myself chatting about the Guidance Automation Toolkit and what you can do.
I have
complained in the past about the shortcomings of the
Whidbey provider pattern (ASP.NET should I say?), which I always regarded as woefully inadecuate as a general purpose pattern for complex blocks and pluggable providers. At
ClariuS it's not our style to just complain, so we got
one of our brightest brains to work on
Enterprise Library and do something about it.
The result is amazing: both simple yet incredible powerful and flexible. I would bet you will see his code in VS Orcas! Don't miss his first
post explaining what it's all about.
One very important area where a dev lead must excel, specially at
patterns & practices where there's a lot of interaction with product groups across Microsoft, is to be able to handle situations smoothly, keep several mind-threads and tasks running at the same time, etc., in other words, you have to be kind of a
juggler with regards to people, projects, and so on.
Peter is very good at it, not only metaphorically, as you can see ;)

You can see Scott, Brian and Brad watch him in awe.
If you happen to be around Buenos Aires, don't miss today's
TechNight that will be an extended version of the presentation
Wojtek and
myself did at the TechEd'05. It's tonight (Aug-12, 7PM @ Microsoft Argentina).
Here are the slides that I'll be showing (along with *lots* of demos/code!!).
We're having our first lab on
CAB, with people from all over the country (US). It went incredible well. People seem to find CAB very useful and intuitive so far, and they certainly think we're solving a lot of the recurring problems they find when building rich smart client applications. We got lots of good feedback. Very engaging overall.
We got a very cool lab room at
building 20 that contained a huge proyector screen and 93 seats with fancy LCDs with movable arms. Impressive.
There was also an entire fridge full of
Haagen-Dazs ice cream, which is always a plus ;)
A couple weeks ago, as we approached an
important milestone for CAB, we had a session where we analyzed the job we did, not only technically but in every aspect. This introspection about how we work and interact as a team led to an interesting set of post-its on the wall:

After we grouped the notes according to the area (from technology/infrastructure to process/doc) and split the possitive and negative ones, we discussed them in turn. (tip: the picture is pretty high quality, so if you zoom enough, you may be able to read some ;)). It was very possitive to be able to express what we think about the project, the team and the environment. It made us think about it, reflect and find points for improvement.
Edjez couldn't avoid going to the whiteboard, of course:

Process-wise, this is a very good practice that we'll surely be applying at
ClariuS.