Sunday, September 27, 2009

BDD in a few hours

What is all that fuzz about BDD? BDD stands for behavior driver design and its about learning to pass the knowledge that you have as a developer to your clients cause as everyone can understand that there is no value if you and your application can do amazing things if your clients have no idea on it.

I am not going to tell you more on that but I am going to provide a series of link of people that speak on both subjects

  • 1st of all you should listen to this great podcast that will explain to you the differences of BDD with TDD and why you should follow that process. Its a long one but I found it very very interesting
Scott Bellware on BDD and Lean Development

Smart and experienced guys in the above podbast eh ? ok after watching the above I am pretty sure that you are convinced that this is the way. Basically it told you what I have stated with bold at the beginning. So where to start what tools to use?.

 

  • then you should watch Rob Conery presenting MSpec here Download it here plus read those 2 posts of him
Learning Behavior Driven Development (BDD)
Make BDD Your BFF

My choise after reading those whould be to go with MSpec and if you want to ease the migration to the new BDD style for your existing TDD proccess better have a look at this series of posts BDD from scratch

I hope you find the above resources enough convincing to get you started on your BDD journey.

ps:If you try MSpec approach on x64 machine in order to integrate TestDriven with MSpec you should change the installation registry file to the following

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Wow6432Node\MutantDesign\TestDriven.NET\TestRunners\MSpec]
"Application"=""
"AssemblyPath"="[YOURDOWNLOADPATH]\\MSpec\\Build\\Debug\\Machine.Specifications.TDNetRunner.dll"
"TargetFrameworkAssemblyName"="Machine.Specifications"
"TypeName"="Machine.Specifications.TDNetRunner.SpecificationRunner"
@="5"


Technorati Tags: ,,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Thursday, September 24, 2009

Xaf Tip # 7 Dangerous Switch

My good friend Martin Praxmarer while we are working on some cool feature for the new ModelDifference eXpand module pointed out the existence of an evil switch

Suppose your team is responsible for creating a module with some kind of Permission so when the system is granted that permission a block of code will be executed, something like

if (SecuritySystem.IsGranted(new MyPermission())){
    //do something

}

and then you pass your module to another team or another consumer and he decides to use the “EVIL ONE” property that is exposed by DevExpress.ExpressApp.Security.SecurityBase class is name IsGrantedForNonExistentPermission and can be changed easily as shown in the next image

image

What it does? As its name states inverse the behavior of the SecuritySystem.IsGranted method.
Default values for SecurityComplex is false but if the consumer of your module set it to true for his own reasons and you have not assign that permission to any role then unwanted code will be executed at your module which is very very very bad. In the scenario we are working on it will corrupt the model!!

So you have to be careful when you write code that uses the IsGranted method cause someone may inverse that behavior

A solution will be to create your own IsGranted method when you do not want that to happen like

public bool IsGranted(IPermission permission){            
    var securityComplex = ((SecurityComplex) SecuritySystem.Instance);
    bool isGrantedForNonExistentPermission = securityComplex.IsGrantedForNonExistentPermission;
    securityComplex.IsGrantedForNonExistentPermission = false;
    bool granted = SecuritySystem.IsGranted(permission);
    securityComplex.IsGrantedForNonExistentPermission=isGrantedForNonExistentPermission;
    return granted;
}

see you at next tip

Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, September 21, 2009

How to zero your application startup time

For this question don’t we all of us spend a lot of time ? But I think it is allowed to use a trick to spend our selves that time.

Add to your model to attributes NotifyIcon, MinimizeOnClose. Since I am using Xaf I am going to present that with it but the code should be very similar to any other windows application

so here are our attributes

image

NotifyIcon: will add a tray icon for your app at the system tray with a context menu that will allow you to terminate your application and display it when you double click the icon

image

public partial class NotifyIconController : WindowController

{

    public const string NotifyIconAttributeName = "NotifyIcon";

    public NotifyIconController()

    {

        InitializeComponent();

        RegisterActions(components);

    }

    protected override void OnFrameAssigned()

    {

        base.OnFrameAssigned();

        Frame.TemplateChanged+=FrameOnTemplateChanged;

 

    }

 

    private void FrameOnTemplateChanged(object sender, EventArgs args){

        if (Frame.Context == TemplateContext.ApplicationWindow && Application.Info.GetChildNode("Options").GetAttributeBoolValue(NotifyIconAttributeName))

        {

            var form = Frame.Template as XtraForm;

            if (form != null)

            {

                IContainer  container=new Container();

 

                var strip = new ContextMenuStrip(container);

                strip.Items.Add(GetMenuItem("Maximize",(o,eventArgs) => changeFormVisibility(form)));

                strip.Items.Add(GetMenuItem("Minimize",(o,eventArgs) => changeFormVisibility(form)));

                if (Application is ILogOut)

                    strip.Items.Add(GetMenuItem("LogOut", (o, eventArgs) => ((ILogOut) Application).Logout()));

                strip.Items.Add(GetMenuItem("Exit", (o, eventArgs) => Application.Exit()));

 

                var notifyIcon1 = new NotifyIcon(container){Visible = true, ContextMenuStrip = strip};

                setIcon(notifyIcon1);

                notifyIcon1.DoubleClick += (o, eventArgs) => changeFormVisibility(form);

            }

        }

    }

 

    private ToolStripMenuItem GetMenuItem(string text, EventHandler clickHandler){

        var item = new ToolStripMenuItem(text);

        item.Click+=clickHandler;

        return item;

    }

 

 

    private void changeFormVisibility(XtraForm form){

        if (form.Visible)

            form.Hide();

        else

            form.Show();

    }

 

    private void setIcon(NotifyIcon notifyIcon1){

        string path = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath),"ExpressApp.ico");

        if (File.Exists(path))

            notifyIcon1.Icon=new Icon(path);

        else{

            Stream resourceStream = typeof(eXpandSystemModule).Assembly.GetManifestResourceStream("eXpand.ExpressApp.Resources.ExpressApp.ico");

            if (resourceStream != null) notifyIcon1.Icon = new Icon(resourceStream);

        }

    }

 

 

    public override Schema GetSchema()

    {

        const string CommonTypeInfos = @"<Element Name=""Application"">

                                            <Element Name=""Options"">

                                                <Attribute Name=""" +NotifyIconAttributeName+ @""" Choice=""False,True""/>

                                            </Element>

                                        </Element>";

        return new Schema(new DictionaryXmlReader().ReadFromString(CommonTypeInfos));

    }

 

}

MinimizeOnClose: attribute will prevent your application from closing

public partial class MinimizeOnCloseController : WindowController

{

    private static bool editing;

    public const string MinimizeOnCloseAttributeName = "MinimizeOnClose";

    public MinimizeOnCloseController()

    {

        InitializeComponent();

        RegisterActions(components);

    }

    protected override void OnFrameAssigned()

    {

        base.OnFrameAssigned();

        Frame.TemplateChanged += FrameOnTemplateChanged;

    }

 

    private void FrameOnTemplateChanged(object sender, EventArgs args)

    {

        if (Frame.Context == TemplateContext.ApplicationWindow &&

            Application.Info.GetChildNode("Options").GetAttributeBoolValue(MinimizeOnCloseAttributeName)){

            var form = Frame.Template as XtraForm;

            if (form != null){

                form.FormClosing += FormOnFormClosing;

                SimpleAction action =

                Frame.GetController<DevExpress.ExpressApp.Win.SystemModule.EditModelController>().Action;

                action.Executing+=(o,eventArgs) =>  editing = true;

                action.ExecuteCompleted += (o, eventArgs) => editing = false;

            }

        }

    }

 

    private void FormOnFormClosing(object sender, FormClosingEventArgs e){

        if (!editing && e.CloseReason == CloseReason.UserClosing)

        {

            if (Application != null) e.Cancel = Application.Model.RootNode.GetAttributeBoolValue(MinimizeOnCloseAttributeName, true);

            if (e.Cancel)

                ((XtraForm)sender).Hide();

        }

    }

 

 

    public override Schema GetSchema()

    {

        const string CommonTypeInfos = @"<Element Name=""Application"">

                                            <Element Name=""Options"">

                                                <Attribute Name=""" + MinimizeOnCloseAttributeName + @""" Choice=""False,True""/>

                                            </Element>

                                        </Element>";

        return new Schema(new DictionaryXmlReader().ReadFromString(CommonTypeInfos));

    }

 

}

Now your application never closes and user can display its UI instantaneously but just double clicking the tray icon

Those 2 controllers are already at eXpand and in next version i think i add a LoadWithWindows attribute that will zero my application load time

Technorati Tags: ,,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Thursday, September 17, 2009

Xaf tip # 6 Linq your Session queries

Pretty silent these days eh? I am working on a big refactoring on DictionaryDifference and have not much time to blog.

But have another tip for my Xaf Tips series today maybe not strictly Xaf but is an XPO tip that you can use with your Xaf applications .

The Problem
Suppose your are a strongly typed fun like me or you want to use linq to query objects inside a transaction.

In order linq to be used with XPO DevExpress provides XPQuery<T> class but unfortunately this do not support transactions.

So the following test fails

var work = new UnitOfWork();
new User(work){UserName = "Sam"};

User firstOrDefault = new XPQuery<User>(work).Where(user => user.UserName == "Sam").FirstOrDefault();

Assert.IsNotNull(firstOrDefault);

The solution
XPQuery<ClassType> also provides a TransformExpression method that takes as an argument a lamda expression.

Aha some extension methods on that would be piece of cake

public static class SessionExtensions
{
    public static int GetCount<ClassType>(this Session session){
        return (int) session.Evaluate<ClassType>(new AggregateOperand("", Aggregate.Count), null);
    }
    public static object GetObject(this Session session, object o){
        if (o== null)
            return null;
        return session.GetObjectByKey(o.GetType(), ((PersistentBase)o).ClassInfo.KeyProperty.GetValue(o));
    }
    public static ClassType FindObject<ClassType>(this Session session,PersistentCriteriaEvaluationBehavior persistentCriteriaEvaluationBehavior, Expression<Func<ClassType,bool>> expression){
        return (ClassType)
            session.FindObject(persistentCriteriaEvaluationBehavior, typeof (ClassType), new XPQuery<ClassType>(session).TransformExpression(expression));
    }
    public static ClassType FindObject<ClassType>(this Session session, Expression<Func<ClassType,bool>> expression)
    {
        
        return (ClassType) session.FindObject(typeof(ClassType), new XPQuery<ClassType>(session).TransformExpression(expression), false);
    }
}

Now the test can be written using Linq To Xpo as

var work = new UnitOfWork();
new User(work){UserName = "Sam"};


User firstOrDefault = work.FindObject<User>(PersistentCriteriaEvaluationBehavior.InTransaction, user => user.UserName == "Sam");

Assert.IsNotNull(firstOrDefault);

and pass succesully !!

These goodies and much more are included at eXpand 

Happy Xaffing and see you at the next tip

Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Saturday, September 12, 2009

I now am a DX-Squad member

Great Saturday today cause I just received my DX-Squad membership today :) and I am very happy.

I wanted to say a big thanks and that i am honored by that invitation. DX-Squad is a similar program to Microsoft MVP. If you want also to be a member read more about it here

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Tuesday, September 8, 2009

Xaf tip #5 Running Controllers everywhere

I recently being asked a lot about a way of making Xaf front end (that is your Solution.Win,Solution.Web) able to host controllers. To many of them i answered that is not possible cause of the Xaf architecture but haven’t thought of it, It was a rushed answer. Anyway i do not have to make a lot of thoughts on it since my friend Panagiotis Kefalidis share that trick with us.

First lets give an example of why you want to run controller in your front end. Many licensing systems need to have access to your executable and through it to your main form in order to protect it. For Xaf the only way to get access to your form is through a controller.

So the trick is to fool Xaf front end to make it behave like a module. Modules are capable to run controllers. And how you can do that?

It is really easy all you have to do is to add a DevExpress.ExpressApp.ModuleBase derived class to your front end like

    public class MyModule:ModuleBase{
        
    }

then goto your WinApplication.Designer.cs

image

instantiate your module at your InitializeComponent method

image

and add it to application’s modules list

image

And you are done!!!!

See you at next tip

Technorati Tags:

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, September 2, 2009

ModelArtifactState Xaf Power to the people

Yesterday i was speaking with my friend John Pouliezos and he asked me how to the implement the following  scenario. John has managed to provide a xaf application as a SharePoint feature. Cool eh? What he wanted is the following: for specific User roles to be able to filter a specific web listview by parsing the current browser url.

Step1 : for specific User roles to be able to filter a specific web listivew

Aha sounds like ModelArtifactState’s job a lot. Cause that module is able to enable or disable behaviours /controllers (doing something) using permissions or the model. We are going to use permissions for this one

So no code is needed for step1 ModelAsrtifactState module is going to help us.

Step 2: John explain to me the urls are going to be like
http://domainName/something/stringtofilterupon/something
or
http://domainName/stringtofilterupon/something or
http://domainName/something/something/stringtofilterupon

So how can we model using permissions that?

Easy :)

We create a permission that inherits eXpand.ExpressApp.ModelArtifactState.Security.Permissions.ControllerStateRulePermission and add one property to define the regex after which we can match the filter that we are interested in and one property to tell to which propertypath to apply that filter.

[NonPersistent]
public class SharePointFilteringPermission:ControllerStateRulePermission
{
    public SharePointFilteringPermission(){
        ControllerType = typeof (SharePointFilterViewController).FullName;
        NormalCriteria = "1=1";
        EmptyCriteria = "1=1";
        ViewType=ViewType.ListView;
    }

    public override IPermission Copy(){
        return new SharePointFilteringPermission();
    }

    public string Regex { get; set; }

    public string PropertyPath { get; set; }
}

Step 3: As you saw in the previous step i have already setup my criteria properties in the constructor and by doing that I told ModelArtifactState module to enable the controller . Then using the model layout editor remove State, Module, ControllerType, NormalCriteria, EmtyCriteria ,ViewType, Nesting properties so hopefully you could end like

image

and next time we assign a permission to a role our permission detail view will be more SharePoint focused

image image

I have also assumed that the regex http://[^/]*/[^/]*/([^/]*) will match the 1st capturing group found (that is the one inside the parenthesis)

Step 4: So up to now we have manage to enable a disabled controller for a role,viewid,objecttype combination what is left is to write that controller .

public partial class SharePointFilterViewController : ViewController
{
    public SharePointFilterViewController()
    {
        InitializeComponent();
        RegisterActions(components);
    }
    protected override void OnFrameAssigned()
    {
        base.OnFrameAssigned();
        Frame.GetController<ArtifactStateCustomizationViewController>().ArtifactStateCustomized+=OnArtifactStateCustomized;
        Active[ArtifactStateCustomizationViewController.ActiveObjectTypeHasRules] = false;
    }

    private void OnArtifactStateCustomized(object sender, ArtifactStateInfoCustomizedEventArgs args){
        if (args.ArtifactStateInfo.Active){
            var sharePointFilteringPermission = ((SharePointFilteringPermission) args.ArtifactStateInfo.Rule.ArtifactRule);
            ((ListView) args.ArtifactStateInfo.View).CollectionSource.Criteria["SharePointCriteria"] =
                CriteriaOperator.Parse(sharePointFilteringPermission.PropertyPath + "=?",
                                       getValueFromQueryString(sharePointFilteringPermission.Regex));
        }
    }

    private object getValueFromQueryString(string regex){
        var input = new Uri(@"http://domainName/something/stringtofilterupon/something").ToString(); //this is for testing purposes
        // use HttpContext.Current.Request.Url instead line above
        return new Regex(regex).Match(input).Groups[0].Value;
    }
}

You see what I have done here? First I disable the controller in the same context as ArtifactStateModule operates then I attach to ArtifactStateCustomized event and only when that is fired for activating the controller I use the info provided to me by the event arguments to filtler my collection

ModelArtifactState module can be found as part of eXpand at http://code.google.com/p/expandframework/

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Tuesday, September 1, 2009

eXpand 0.0.0.10 is out

Latest version of eXpand is out and recompiled with Xaf 9.2.4 version

New Module Additions
AdditionalViewControlsProvider
Validation
ModelArtifactState
WizardUI

see (Bend Xaf Applications with Model Artifact State Module)

Fixes enhancements via Google issues here

Get latest version of expand here http://code.google.com/p/expandframework/

Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!