Thursday, March 12, 2015

Caliburn.Micro for Windows Forms and Visual WebGUI


On a post some 3 years ago, answering my own question "Can we port Caliburn.Micro to WindowsForms?", I said "Not yet. Several problems have to be solved first" and went on about all the issues to be solved. It turns out most problems were already solved by Dan Durland's port, that was hidden among the 100+ forks of Caliburn.Micro.

The port isn't complete and there are some issues, but overall, is a very good port.
  • One of the main issues was the lack of DependencyObject and DependencyProperty classes outside the WPF world. These classes are partially implemented, just enough the make the port easier to do.
  • Plain System.Windows.Forms events replace the functionality that is provided by the System.Windows.Interactivity Trigger stuff (EventTrigger and TriggerAction) used on regular Caliburn.Micro.
  • As ToolStripItem descend from System.ComponentModel.Component (and not from System.Windows.Forms.Control), a ToolStripItemProxy control is provided. The framework manages the life cycle of this control automatically, so you can ignore it altogether.
  • On the other hand, you can't ignore the provided ContentContainer control that replaces Panel. It knows about what ViewModel it is bound to, and is intended to host the UserControl that you want to load on your shell Form.
  • The message.attach feature is implemented as a string on the Tag property of the Button or whatever System.Windows.Forms.Control descendent you want.
If the latter feature implementation proves to be a problem (some people might use the Tag property for other purposes), the plan B is to implement this feature as a DependencyProperty.


The port doesn't support some very interesting Caliburn.Micro features, all in the Action parameters area:
  1. Support for SpecialValues parameters ($eventArgs, $dataContext, $source, $executionContext and $view)
  2. Support for $this parameters
  3. Support for object.property parameters
  4. Binding to object.property parameters
  5. Guard method re-evaluation on object.property change
Nonetheless, and repeating what I said before, I would say that overall, it is a very good port.

The MVVM FX project took Dan Durland's port as a working base and improved on it. All the issues outlined above were solved. Point 3 was solved with the help of MVVM FX own binding library, that is based on Truss by Kent Boogaart.

MvvmFx.CaliburnMicro went a step further and provides interesting features that are absent on regular Caliburn.Micro:
  • Support for $this.property parameters
  • Binding to $this.property parameters
  • Guard method re-evaluation on $this.property change
There is a feature that might prove interesting and is hold back until proven necessary:
  • Support for SpecialValues.property parameters

The Visual WebGUI project follows quite closely the Windows Forms implementation, but addresses two major differences:
  • There is no such thing as a UIThread under WebGUI.
  • A VWG application starts by building a Form (no Program.cs file) while Windows Forms applications uses Caliburn.Micro to build the shell Form.
All the samples have two projects: Windows Forms and WebGUI. Both projects share the exact same ViewModel

While Dan Durland's port is based on Caliburn.Micro version 1.3.1, the MVVM FX source was updated to 1.5.2, including all post 1.5.2 fixes that were applied before the regular Caliburn.Micro was ported to BCL.

A final note to say that MvvmFx.CaliburnMicro is formally in beta stage, but is stable enough for you to start developing with it. As soon as the samples are ready, it will be release, both on Codeplex and on NugGet, both for Windows Forms and Visual WebGUI.

Sunday, July 22, 2012

CSLA and Visual WebGUI


I don't like ASPX. I tried both flavours, with and without AJAX. I hate several things about ASPX
  • programming in 4 languages (C#, HTML, Javascript, CSS)
  • ViewState
The normal way to write ASP.NET applications is to write stateless pages. You can use a state server but most of time you just use ViewState. Neither one is a good solution. ViewState means your server sends the browser an invisible field with state information. When you post back, the ViewState information travels back to the server. As you might imagine, all this data that is sent back and forth doesn't help your Web application to become faster.

The worst part of ASP.NET is the 4 language issue. I guess I don't need to explain in detail why it doesn't help to simplify the development process or to make it faster for that matter.

Enter Visual WebGUI. No ViewState and only one programming language: C# or VB.NET.

For those unfamiliar with Visual WebGUI, it's a WEB framework that is build around the "empty client" concept. All the developer sees is the full set of Windows Forms controls. You write your code on C# or VB.NET and forget Javascript, CSS and HTML exist. If you have a working Windows Forms application, porting it to WebGUI is really easy. The browser is used just to display the visual side of the controls and to return user input back to the server - the concept of "ViewState" doesn't exist.
  • The browser is running a JS kernel that relays low level events to the server: user pressed a key, user clicked at point (X,Y), etc.
  • The library handles the low level events like the Windows Forms library does.
  • The server is running your application and it doesn't need to reload state everyt time you click somewhere.
This results in applications easier to write:
  • one development language only
  • you don't loose context between page submissions (you don't have to submit pages)
and applications that run faster
  • less data flows server => client => server (namely ViewState)
  • application doesn't need to reload context from BD or whatever
Going back to Visual WebGUI sounded like a good idea. From my past experience with CSLA + Windows Forms and CSLA + WebGUI, I knew CSLA needs some UI support classes and UI controls. So I ported them to Visual WebGUI. It was really easy and it didn't came as a surprise, since WebGUI replicates the Windows.Forms namespace.

So I was developing this application. I had the BO and DAL done for CSLA Business Objects library and the UI part was well advanced. The customer wanted a WEB UI but I chose to write two UIs:
  • Windows Forms
  • WebGUI
The first is used as a test and control project. I put the ideas to screen under Windows Forms. Of course there is some overhead to take this double UI approach. The overhead isn't that big since it's so easy to port Windows Forms to WebGUI.

While it's impossible to find a UI technololy more stable than WinForms, Visual WebGUI has made some very important progress but it's not the most stable technology around. If something doesn't work under WinForms, no bother to try it under WebGUI.

The big advantage on this approach allows me to see in WinForms  what I can expect from WebGUI. If the behaviour doesn't match, I have a WebGUI issue. I could develop directly on WebGUI. If some control didn't behave the way I wanted, it would be difficult to tell whether it was the developer's fault or a WebGUI problem.

So what's the bottom line of this blog entry?

CslaContrib.WebGUI source code was posted on this CSLA.NET thread. In a couple of weeks it will be published on CSLA .NET Contrib Codeplex site too.

Sunday, June 10, 2012

MVVM FX - Windows Forms and Web


Things are moving fast. Two weeks ago I was looking for a WindowsForms MVVM framework. Today I published it at http://mvvmfx.codeplex.com/. This project used to be managed by Sam Bourton that kindly transferred project ownership to me.

Why the insistence on using the FX expression? Why not WF or WinForms? As the project title says MVVM FX - base framework for Windows Forms and Visual WebGUI, the project scope is not only WinForms but also Visual WebGUI. It's easy to port Windows Forms code to Visual WebGUI since Gizmox tryed very hard to mirror System.Windows.Forms namespace as Giszmox.WebGUI.Forms.

In case you don't know, VisualWebGUI it's an empty client technology for Web. The browser is a "dumb terminal" - a bit like the Sun Network Computer concept: the browser is used to display content and receive user input (mouse and keyboard). There is a Javascript kernel that handles display messages from the server and relays user input back to the server. Incidentally it also acts as a keep alive agent, to let the server know that the client is still there and informing the user in case the server doesn't reply. These messages are very small (nothing like the dreaded viewstate of ASPX) and the system is indeed very responsive.

All these features are wrapped as Windows Forms technology - the only desktop technology available when Gizmox started this product.

There are several consequences to using Visual WebGUI:
  1. you write code in C# or VB.NET
  2. you don't have to know Javascript unless you want to make your own low level control
  3. it's not easy to do MVVM (just like WinForms)
Number 3 above is a downside that this framework will overcome.

Tuesday, June 5, 2012

Iterating an enumerable in C#


Suppose you have an enumerable and you need to iterate it in order to do something. I know that's not a very common need but it may happen. It happened to me and I came up with this solution.


using System.Collections.Generic;

namespace Events
{
    public enum MenuItemEvent
    {
        Click,
        Select
    }

    public class MenuItemEvents : List<MenuItemEvent>
    {
        public MenuItemEvents()
        {
            var item = 0;
            while (true)
            {
                if (((MenuItemEvent) item).ToString() == item.ToString())
                    break;

                Add((MenuItemEvent) item);
                item++;
            }
        }
    }
}

Now you can foreach every element of the enum.

Sunday, May 27, 2012

WindowsForms Truss databinding


Yesterday I blogged about MVVM for WindowsForms and I mentioned Truss, the databinding library à la WPF that is UI independent. Note I said independent, not agnostic. In fact, it can bind to:
  1. an ordinary property contained in an object that implememts INotifyPropertyChanged
  2. a DependencyProperty of a DependencyObject
  3. an ordinary property of a WindowsForms control
When we say DependencyProperty you know it's WPF (or Silverlight).How come it knows how to bind to a property of a WinForms control?

Truss implements a binding strategy that uses the Microsoft PropertyNameChanged Pattern. Given a property Address, Truss attaches itself to the AddressChanged event. It happens properties of WinForms controls raise this event instead of  the PropertyChanged(<propertyname>) event that is raised by INotifyPropertyChanged properties.

A word about binding expressions

In our example, we have:
  • MainForm - the view with two text boxes: txName and txAddress 
  • MainFormViewModel - the ViewModel that contains a Model property of type MainFormModel
  • MainFormModel - the model with two string properties: Name and Address
The listing included in this post aren't MVVM examples, so I won't discuss the technical MVVM side. For this example, we pass the ViewModel reference to the view on the constructor method. On the form Load handler, we bind the model properties to the text boxes in two different ways:
  • using a simple string path expression
  • using a lambda expression
If you are going to inject your bindings using convention over configuration, you must use the first variation.

    Listing 1 - Single part path
    namespace WinFormsBinding
    {
        public partial class MainForm : Form
        {
            private MainFormViewModel _viewModel;
    
            public MainForm(MainFormViewModel viewModel)
            {
                _viewModel = viewModel;
                InitializeComponent();
            }
    
            private void MainForm_Load(object sender, EventArgs e)
            {
                var bindingManager = new BindingManager();
                bindingManager.Bindings.Add(new Binding(this.txAddress, "Text", _viewModel.Model, "Address"));
                bindingManager.Bindings.Add(new TypedBinding<TextBox, MainFormModel>(
                    this.txName, s => s.Text, _viewModel.Model, t => t.Name));
            }
        }
    }
    

    You might be tempted to refer the root object and use a multipart path.

    Listing 2 - Multi part path
    bindingManager.Bindings.Add(new Binding(this, "txAddress.Text", _viewModel, "Model.Address"));
    bindingManager.Bindings.Add(new TypedBinding<MainForm, MainFormViewModel>(
        this, s => s.txName.Text, _viewModel, t => t.Model.Name));

    Well don't. This doesn't work. I'm not sure whether this should work under Truss. I intend to come back on this subject.

    As a closing subject, on my quest for MVVM for WindowsForms I found another interesting piece of MVVM stuf. Magical.Trevor implements convention over configuration to find a View for a given ViewModel and bind both together. The same pattern is also used to self-bind:
    • Button Click event to methods
    • TextBox Text property to string properties
    Magical.Trevor isn't a port of Caliburn.Micro for WindowsForms. As Mike Minutillo says, it's based on some of the ideas found in Caliburn.Micro.

    Saturday, May 26, 2012

    MVVM for WindowsForms


    Some years ago, I became interest in MVVM for developing WPF (and Silverlight) projects. After much research, I chose Caliburn.Micro: small, simple yet powerfull. I like the convention over configuration approach. In spite of MVVM being accused of making you write more code, Caliburn.Micro's convention over configuration means it has the ability to inject the binding code and makes you write less code. Your view classes have no code behind at all: the .cs file is absent. As Caliburn.Micro injects the InitializeComponent() call you don 't need that file at all. You can't write code behind by mistake if there is no file to do it.

    Another nice feature I found in Caliburn.Micro is the implementation of the Screen Activator pattern. You shoudn't open and close views at your will and catch the "isn't saved" issue sometimes and miss it some other times. The “Screen Activator” Pattern is explained by Jeremy Miller. I won't explain it here but it's important to emphasize that it fits the general view separation pattern (MVC, MVP, MVVM).

    Recently I was asked to develop something in WindowsForms. It started life as usual WindowsForms projects: event handlers, more event handlers and even more event handlers. It  became obvious something was missing: screen activator pattern for starters and while we are at it, MVVM for WinForms.

    I asked Google about it and got no obvious results. I asked two of my techies co-workers if MVVM for WindowsForms was possible. Both gave me the exact same answer: "No way! WindowsForms is missing the rich bindings of WPF and Silverlight (OneTime, OneWay, TwoWay, OnewayToSource) and it is also missing the TypeConverters."

    First things first.

    • Screen Activator Pattern for WindowsForms - you can find it here, ported by jagui
    • Rich Bindings and TypeConverters - Truss by Kent Boogaart, does it in an UI independent way
    • Commands - WPF Application Framework (WAF) has a WafWinFormsAdapter project that takes care of some MVVM stuff namely commands


    Again, can we have MVVM for WinForms?

    Yes we can. We have all the pieces. We just have to glue them together.

    Can we port Caliburn.Micro to WindowsForms?

    Not yet. Several problems have to be solved first. Remove four references from Caliburn.Micro and you'll see what I mean:
    - WindowsBase
    - PresentationCore
    - PresentationFramework
    - System.Windows.Interactivity


    The are four bigs issues identified so far:
    1. Get rid of DependencyObject and DependencyProperty that pops a bit everywhere in CM
    2. Replace FrameworkElement and UIElement by WindowsForms objects
    3. Stick to WAF's implementation of Command or replace EventTrigger
    4. Replace DataContext

    There are also a lot of small issues that I hope can be solved easily. I'll report back.

    Saturday, August 20, 2011

    VS 2010 Setup Project - how to upgrade?


    Setup projects under VS2005 and VS2008 were easy to upgrade:
    1. select the Setup project
    2. go to the Properties tab
    3. update the Setup project Version
    4. accept VS suggestion to change the Product Code
    5. build the Setup project
    This isn't enough under VS2010.
    Is it a bug? In fact no. It happens that VS2010 uses the installer in a smarter way. The MSI generated by VS2010 only replaces changed assemblies. The same principle is used by ClickOnce and it makes upgrades faster.

    The question is: what is a changed assembly? Different update date? Different size? Not at all. Assemblies are different when they have a different File Version. As simple as that.
    I'm not sure ClickOnce uses this criteria to identify different assemblies.

    Upgrading a Setup project under VS2010 is a bit more complicated:
    1. update the File Version of all assemblies that are changed for this upgrade
    2. generate new binaries for these assemblies
    3. select the Setup project
    4. go to the Properties tab
    5. update the Setup project Version
    6. accept VS suggestion to change the Product Code
    7. build the Setup project
    To know more about this subject and understand why you need to do it this way under VS2010, you can read an interesting discussion.

    So what about the SolutionInfo and the Consistent Version Numbers Across All Assemblies technique? It's a way to make sure you don't forget to update the File Version of all assemblies, even if they didn't change. It's a kind'a "fail safe" upgrade. Of course you risk to replace too many assemblies that in fact didn't need to be replaced. The choice is yours.

    Sunday, July 31, 2011

    How "dynamic" made my life easier


    Some coworker said once "Every time you hear dynamic means a load of troubles is coming by". I didn't agree. I know lots of interesting stuff can only be done using Reflection and even Reflection.Emit. Just to give some context, you are talking about Microsoft Framework 4.0 and the new type dynamic type declaration.

    As you know C# is a statically typed language. As you also know, this means you must declare the type of every variable, field or property, before you can use it. The var keyword didn't change that rule a bit. Using var you are implicitly declaring tha variable type. The compiler knows the correct type of  var and the keyword is replaced by the correct type at compile time.

    Let's rephrase: the type of each variable, field or property must be known at compile time. Then Framework 4.0 and _Dynamic Language Runtime_ brought us dynamic. We must change the definition above as the real type dynamic is unknown at compile time. A dynamic type can be any type at all so it's legal to do any operation you like with it. The compiler won't complain about it being incorrect as it doesn't know the real type.

    You can argue that System.Object could do the the trick but you also know the range of operations you can do with System.Object is very narrow and you have to cast it to another type in order to get the same kind of usability, I mean in order to support all operations other types support. No more limitations like that:
    • declare a variable as dynamic
    • your first assignmenet to this variable defines the real type it will have
    • the legal or illegal operations will be evaluated after this assignement
    What's the catch? Incompatibilities that couldn't show on compile time will show at runtime. So if you practice "jerk programming", you will get "a load of troubles" and my coworker's statement will prove correct.

    What do I need dynamic for?
    The classical problem is the "custom properties" issue. You have an business application but every customer wants its own set of extra properties and the requirements of the customer can overcome your worst scenarios/nighmares. You could go the Reflection.Emit way but that's really hard for most programers. Let's try the dynamic way.

    Define you CustomPropery class like this:

    using System;
    
    public class CustomProperty
    {
        #region Private Fields
    
        private string _name = String.Empty;
        private string _type = String.Empty;
        private dynamic _value;
    
        #endregion
    
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    
        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }
    
        public dynamic Value
        {
            get { return _value; }
            set { _value = value; }
        }
    }
    


    Notice dynamic is used both on the field and on the property.
    I suppose you will now read the CustomProperty definitions from some storage be it a database, XML file, it really does't matter.

    Now you need a method that converts the type that you read as a String into a Type.

    private static Type GetDataType(string type)
    {
        Type propType = Type.GetType(type);
        if (propType == null)
            propType = Type.GetType("System." + type);
        if (propType == null)
            propType = Type.GetType("App.CustomProperties." + type);
    
        return propType;
    }
    


    Just to put it all together, after reading the definitions to a prop of PropertyInfo type, you assign the real type like this:

    var customProperty = new CustomProperty();
    customProperty.Name = prop.Name;
    customProperty.Type = prop.PropertyType.Name;
    
    Type targetType = GetDataType(customProperty.Type);
    if (targetType != null)
    {
        if (targetType.IsEnum)
            customProperty.Value = ConvertStringToEnum(targetType, "");
        else if (targetType == typeof (Int16))
            customProperty.Value = (Int16) 0;
        else if (targetType == typeof (Int32))
            customProperty.Value = (Int32) 0;
        else if (targetType == typeof (Int64))
            customProperty.Value = (Int64) 0;
    }
    else
    {
        customProperty.Value = " ";
        customProperty.Value = string.Empty;
    }
    


    After the first assignement juts to define the real Type,  you can now take care of assigning the real value, knowing it will have the correct Type.

    In this example I need the properties for use in a PropertyGrid. In each grid row, I show the customProperty.Name followed by the customProperty.Value. The sample presented here is very limited in scope and isn't really a How To. The point is:
    1. there is no keyword to define the real type of a dynamic variable/field/property
    2. the real type is defined by the first assignement
    3. do this assignment as soon as you know the real type
    4. assign the actual value after the previous assignment

    Sunday, July 10, 2011

    You can't serialize Dictionary


    Too bad:)
    I have to make a class MyDictionary with two field, key and value, both beeing strings. Then maybe I can serialize a List.
    Then again, this guy has a Solution!


    Friday, May 20, 2011

    Caliburn.Micro and CSLA framework


    What's better than one framework? Two frameworks!

    Back in February I merged Csla.Xaml.ViewModel with Caliburn.Micro.Screen class and the result was a new ScreenWithModelBase class added to my version of Caliburn.Micro.

    This Caliburn.Micro extension for CSLA.NET makes life easier for those who want to use both frameworks and makes Caliburn.Micro a very interesting alternative to the BXF framework that is so popular on the CSLA world (as Rocky uses it on all Silverlight project samples).

    Yesterday an old announcement on CSLA.NET forum received some attention and Jonny Bekkum asked me whether he could add this class to CslaContrib project. That was done a while ago.

    Sunday, April 24, 2011

    Technical Note: Silverlight code for CSLA 4



    This note was written for CslaGenFork project.

    Summary
    When using a Silverlight client, your application must always use an application server. Because of Silverligt restrictions, the business objects library DLL must be different on the Silverlight client and on the application server. In this post we will see what are those restrictions, the solutions to the issues they raise and how to use the generated code. In fact this post summarizes what needs to be changed in order to run CSLA code under Silverlight.

    N.B. - CSLA Silverlight changes are numbered and marked in bold.


    I - Silverlight restrictions

    Due to security reasons, there are a lot of things you can't do on Silverlight code. For what CSLA cares, there are three things you can't do under Silverlight:
    1. Access a database server, namely SQL Server
    2. Make synchronous calls to the application server
    3. Use reflection on non-public members of other classes (one class can't use reflection on private members of another class)
    Let's analyse the CSLA solutions for each one of these restrictions.


    II - CSLA solutions

    1. The Silverlight client must receive and send the data through the application server.

    CSLA.NET automatically takes care of routing all DataPortal calls to the application server. If CSLA.NET doesn't find a suitable DataPortal method in the client code, it routes the call to the application server.

    1.1. DataPortal_Create is a special case because most of the times you want it to run locally.
    Regular CSLA uses the attribute [RunLocal] to mark DataPortal methods that must be run on the client (client side DataPortal concept). When DataPortal_Create exists, it's a strong candidate to run client side unless you need to load object default values from the database.
    On Silverlight, DataPortal client side methods accept an extra parameter DataPortal.ProxyModes.LocalOnly that forces the DataPortal code to run locally.

    1.1.1. On the Silverlight client, to run DataPortal_Create locally, there must be a specific asynchronous DataPortal_Create method.
    The Silverlight signature is different from the equivalent method that may exist on non-Silverlight clients.
    The Silverlight signature looks like this:
    public override void DataPortal_Create(Csla.DataPortalClient.LocalProxy.CompletedHandler handler)
    The regular CSLA signature looks like this:
    protected override void DataPortal_Create()

    1.1.2. On the Silverlight client, there must be a specific asynchronous factory method that invokes DataPortal.BeginCreate passing that extra parameter.
    The Silverlight invocation looks like this:
    DataPortal.BeginCreate(callback, DataPortal.ProxyModes.LocalOnly);
    The regular CSLA asynchronous invocation looks like this:
    DataPortal.BeginCreate(callback);

    N.B. - All DataPortal_XYZ methods can run locally. This might be useful in scenarios where the Silverlight client is using REST or SOAP services to interact with the database.

    2. The Silverlight client must invoke the application server asynchronously.
    CslaGenFork can generate synchronous or asynchronous code. When generating Silverlight, asynchronous code is always generated. This includes:

    2.1. Asynchronous LazyLoad for properties (may be synchronous or asynchronous under regular CSLA, but never both at the same time).
    If both options for synchronous and asynchronous code generation are set, under Silverlight the getter code will be asynchronous code and synchronous code for non-Silverlight environments.

    2.2. Asynchronous Factory methods (may be both synchronous and asynchronous under regular CSLA).
    The Silverlight and synchronous factory methods are called asynchronously and they invoke the DataPortal methods asynchronously. CGF generates synchronous and asynchronous code according to the settings (no conditions here).

    N.B. - Business rules that must get data from the application server must also run asynchronously. That's a problem that must be addressed by the rule developer but beyond CslaGenFork concerns.

    3. On the Silverlight client, all usual private or protected member must be public.
    This issue is solved with code like this:
    #if SILVERLIGHT
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        public ...
    #else
        private ...
    #endif
    The EditorBrowsable attribute intends to hide the member from InteliSense (and from the developer) as a way not to encourage its use.
    This issue shows on the following cases:

    3.1. public PropertyInfo declaration (private under regular CSLA)

    3.2. public class constructor (private under regular CSLA)

    3.3. public AddObjectAuthorizationRules (protected under regular CSLA)

    3.4. public DataPortal methods (some are private or protected under regular CSLA)


    III - What is generated and how to use it

    As of November 2011, CslaGenFork generates both Encapsulated Implementation and Encapsulated Invoke DataPortal models (according to Using Csla 4 ebooks classification). The usual 2 files are generated: the .Designer file and the extended file.
    The extended file is where CGF puts the commented partial method implementation of the Pseudo Event Handlers. Note that all these methods run server side. If you are regenerating a project, you should put a pair of conditional compilation directives around the whole region:
    #if !SILVERLIGHT
    #endif
    In the .Designer file you will also find a lot of directives just like the above. According to the compilation symbols defined in your project, some parts of the code are ignored. This way you take the same source code and get two different DLLs: one for the Silverlight client and another for the application server. The later can also be used on:
    • WPF client application
    • WPF application server
    • ASP.NET application server
    N.B. - For Windows Forms there are other issues (ListBase versus BindingListBase inheritance) that prevent the use of the same DLL.

    One way to accomplish this goal is to make a copy of all source files and put each copy in a different project: one on a Silverlight Class Library project and another on a Windows Class Library project.

    A more usual approach does the same thing except you don't copy the files but use kind'a shortcuts. Say your main project is the Windows Class Library. Put the files there and build it as usual. On the Silverlight Class Library project, add all folders needed by the project. After that, go to each of the folders and add existing items. Now that's the magic part: navigate to your main project files, select the files and instead of clicking Add, click the small down arrow and click Add As Link.

    Tiago Freitas Leal

    Links:
    CSLA.NET
    CslaGenFork

    Monday, March 14, 2011

    Injecting a logger in Caliburn.Micro



    CM defines a ILog interface. The LogManager class implements a NullLog. It's CM default implementation. As it is, it's not very useful. I looked around and found How To Do Logging with Caliburn.Micro. It works all right on my WPF project. The question now is I don't want to specify my logger in code, I want to use DI/IoC pattern (Dependency Injection/Inversion of Control). This means I want to specify the logger in my App.config. Sounds easy, been there, done that.

    1) Create a project Logger.
    2) Add a reference to the Caliburn.Micro assembly you are using (be it WPF, Silverlight or WP7).
    3) Add references to NLog and log4net and whatever logging library you might want to use. I'm using NLog 1.0 Refresh and it works all right.
    4) Copy the ILog implementations from How To Do Logging with Caliburn.Micro to this project.
    5) Change the namespace of the classes to Logger and make the classes scope public.
    6) Build the Logger project just to make sure everything is ok.
    7) Go back to your main project and remove all references to NLog, log4net, etc.
    8) On your main project open App.config and a add a line in the appSettings section:
    <add key="Logger" value="Logger.NLogLogger, Logger" />

    Now we need a method to inject the class as our logger.

    9) On your main application, add a class like this:

    using System;
    using System.Configuration;
    using Caliburn.Micro;

    namespace CaliburnMicroWpfApp.Framework
    {
        /// <summary>

        /// Manages the injection of the logger.
        /// </summary>
        public static class LoggerFactory
        {

            /// <summary>
            /// Creates logger instance.
            /// </summary>
            /// <returns>The ILog instance.</returns>
            public static ILog GetLogger(Type type)
            {
                Type loggerType;

                var loggerTypeName = ConfigurationManager.AppSettings["Logger"];
                if (!string.IsNullOrEmpty(loggerTypeName))
                    loggerType = Type.GetType(loggerTypeName);
                else
                    throw new NullReferenceException("Logger");

                if (loggerType == null)
                    throw new ArgumentException(string.Format("Type {0} could not be found", loggerTypeName));

                return (ILog)Activator.CreateInstance(loggerType, type);
            }
        }
    }


    10) Call the GetLogger method in your bootstrapper class. Mine is like this:

    using Caliburn.Micro;
    using CaliburnMicroWpfApp.Framework;
    using CaliburnMicroWpfApp.ViewModels;

    namespace CaliburnMicroWpfApp
    {
        public class DefaultBootstrapper : Bootstrapper
        {
            static DefaultBootstrapper()
            {
                LogManager.GetLog = type => LoggerFactory.GetLogger(type);
            }
        }
    }


    11) Don't forget to add a nlog section to your App.config or a NLog.config file.

    That's it.

    Saturday, February 12, 2011

    Caliburn.Micro WindowsManager.Show_XYZ methods



    While Rob Eisenberg is writing The Window Manager I might as well share my findings about it.

    There are 3 Show_XYZ methods:


    • ShowDialog() - shows a modal window
    • ShowWindow() - shows a modeless window
    • ShowPopup() - shows a popup
    For ShowDialog() and ShowWindow(), your view should be a Window. If your view is a UserControl behind the scene Caliburn.Micro will create a window to host it. You call the method like this:

    public void ShowModal()
    {
        var wm = new WindowManager();
        var vm = new ModalViewModel();
        wm.ShowDialog(vm);
    }

    public void ShowWindow()
    {
        var wm = new WindowManager();
        var vm = new WindowViewModel();
        wm.ShowWindow(vm);
    }


    I found ShowPopup() a bit less intuitive to use. Your view must be a UserControl and not a Popup as you might expect.

    public void ShowPopup()
    {
        var wm = new WindowManager();
        var vm = new PopupViewModel();
        var settings = new Dictionary();
        settings.Add("StaysOpen", false);
        wm.ShowPopup(vm, null, settings);
    }


    That's it. happy coding!


    UPDATE - You can find a detailed artcle on WindowManager at Caliburn Micro Part 5: The Window Manager.

    Sunday, October 25, 2009

    Carta de intenções

    Comecei a programar em Basic no ZX Spectrum. A minha segunda linguagem foi Assembler Z80 e tive mais umas quantas até a vida me levar para outros lados. Mas acabei por estar de volta aos ambientes de desenvolvimento.

    Mudou tudo! Basta procurar na net e vemos que mudou tudo, e já há bastante tempo. Muito mais de metade do que está disponível na net está em inglês. Uma parte significativa foi feita pela Microsoft e não está exactamente bem feito. Há muita confusão de conceitos e é difícil encontrar o caminho.

    CARTA DE INTENÇÕES do Tribuna Tek

    1. Os temas deste bloque serão temas ligados ao desenvolvimento em sentido lato: arquitecturas, técnicas de modelação, metodologias de desenvolvimento, metodologias de projecto, técnicas de programação, e uma série de temas soltos que não vou agora tentar agrupar e classificar: OOPS, testes unitários, integração contínua, controle de versões, etc.
    2. O que faço actualmente é em .NET pelo que os exemplos serão desse mundo.
    3. Os textos terão um objectivo de divulgação (pedagógico) ou não.
    4. Os textos poderão ser críticos ou não.
    5. Os textos poderão ser reflexões do dia, lamentos ou cantos de vitória.
    6. Os textos poderão estar certos ou não.
    7. Este bloque não é um guia de aprendizagem, não pretende ser completo ou exaustivo, nem sequer fazer doutrina.

    Thursday, August 20, 2009

    Testes de Software

    O tema dos testes de software é um tema muito popular, sobretudo agora que há uma iniciativa legislativa da União Europeia que visa responsabilizar as software houses pelos danos causados pelos erros do software.

    Mesmo antes de sair para almoçar, entrevistámos o colega Cicrano (ou seria a colega Beltrana? Com a fome nem me lembro bem...)

    P – Como é que se testa o interface gráfico? – perguntámos.
    R – Carrega-se em todos os botões até dar erro – ouvimos de resposta, mesmo antes do (ou da) colega picar o cartão e correr para o elevador.

    Apaziguada a fome, fizemos uma ligação VoIP para o nosso amigo de infância Abílio Gatos, personalidade notável no mundo do software e radicado desde criança nos USA.

    P – Está lá, hello?
    R – Hello, yes, quem fala? – ouvimos num sotaque californiano que não esconde as origens lusitanas.
    P – Como está o meu amigo Abílio Gatos?
    R – Oh seres tu my friend! Eu já não ser Abílio Gatos; mudar para nome americana e ser Bill Gates. Ser nome parecida LOL
    P – Perdoa-me Bill, mas esqueço-me sempre do teu nome de magnata do software.
    R – Eu agora ser reformada. Já não ser magnata.

    Tossi com ironia e passei ao cerne da questão.

    P – Olha Bill, os meus colegas dizem-me que para testar o interface gráfico tenho que carregar nos botões todos e ver se dá erro.
    R – Ho ho ho, I mean LOL. E se não dar erro mas estar wrong output? Não, nada disso. My corporation fazer melhor software do mundo, fazer software para testes UI e estar muito bem cotada no NYSE. Queres comprar acções meu corporation?
    P – Ó Bill explica lá como é isso: o software vai ver se os pixels mudaram de cor? Se vou dizer isso aos meus colega, eles partem-se a rir.
    R – What a silly idea! Pixels mudar de cor? You make me ROTFL...

    Depois de recuperar do ataque de riso, mandou-me este video QuickTime.

    P – Obrigado pelo video que mandaste. Mas este software (http://seleniumhq.org/) não é da tua empresa. A tua empresa não tem software deste género?
    R – Of course we do! Isto ser only prova de bom vontade com Open Source. Meu corporação ter soluções world best e fazer subir cotação na bolsa. Mas bom vontade com Open Source também fazer subir cotação na bolsa.
    P – Então explica-me lá que soluções é que a tua empresa tem.
    R – Ok, but tens que comprar acções meu corporation. We have the new Microsoft UI Automation Library, which is included in the .NET Framework 3.0 as part of Windows Presentation Foundation (WPF). Podes usar o UI Automation Library para testar Win32 applications, .NET Windows Forms applications and WPF applications. Tu ver este MSDN Magazine article.
    P – Obrigado. Mas pelo que vejo da tua resposta, esse software não resolve o problema dos testes de aplicações ASP.NET...
    R – Ok, ok. Tu usar Selenium. Se não gostar, try this other solution using Windows Power Shell. Tu ver outra MSDN Magazine article.
    P – Resumindo, estas soluções escrevem valores como se fossem utilizadores a escrever no teclado e procuram padrões de texto no ecrã.
    R – That’s correct. E não ver se pixel mudar de cor LOL... Tu ainda acender cigarro com dois silex? LOL

    Fiquei amofinado com’ó-caraças com esta alusão aos silexes. Mas, estoicamente, ignorei o insulto.

    P – Já percebi como se fazem os testes do interface gráfico. Se além destes testes, se eu fizer testes unitários e testes à base de dados, fico com uma belíssima cobertura de testes automáticos. Mas tenho ainda um problema: há um controle ActiveX que é muito usado e não sei como incluí-lo nos testes.
    R – That’s bad. You esquecer ActiveX. You usar AJAX or Silverlight. Com ActiveX ser impossivel automated UI testing.
    P – Mas Bill, isso de preparar/escrever os testes demora muito tempo. E como vocês dizem “time is money”...
    R – LOL e procurar bugs ser mais rápida? E pagar indemnização ser mais barata? E perder cliente por causa de muitos bugs ser bom negócio? You ask anyone: good testing makes good software. Poucos bugs gasta pouco tempo a procurar e corrigir bugs.

    P – Olha Bill, gostei de falar contigo. Foste muito simpático e ajudaste-me muito. Agradeço imenso.
    R – You’re welcome. Tu teres que comprar acções meu corporation pois Google operating system vai ser fiasco e eu ficar homem mais rica do mundo again.

    E lá comprei umas acçõezitas...