Pages

Thursday, February 27, 2014

Disable auto complete on a form control

As a pattern, Dynamics AX has an auto complete feature in form controls.

There is a way to disable it though, programmatically.


There's the delAutoCompleteString method on the FormRun class. The name is pretty straight-forward.


We must override the control's textChange method to call it:

public void textChange()
{
    super();

    // Since we're overriding a control's method, "this" means the instance of the control.
    // We could also reference it by its name, if the AutoDeclaration property is Yes.
    element.delAutoCompleteString(this);
}


With that single line of code, we can disable the auto complete feature.

Thursday, February 6, 2014

Create implicit and explicit user-defined type converions in C#

I bet you had to write tons of static methods to convert between a user-defined type to another type, and that it always made your code very ugly and verbose, also creating lots of "helpers".

Well, C# has a nifty way to facilitate that for us.

Apart from using the keyword operator to overload default arithmetic operations, we can use it in conjunction with the implicit and explicit keywords to create new user-defined type conversions. One should already know the difference between explicit and implicit conversions.


Implying it


By defining a new operator using the implicit keyword, you can easily hide all of those static method calls, and write simple code, such as this:

var foo = new Foo
{
    Size = 10,
    Name = "Foo"
};

Bar bar = foo;

// Notice that we're not talking about polymorphism, 
// as there's no inheritance between the classes:
class Bar
{
    public string BarInfo { get; set; }
}

class Foo
{
    public int Size { get; set; }
    public string Name { get; set; }       
}

To do that, we simply defined a new implicit operator between the two types, such as:

public static implicit operator Bar(Foo foo)
{
    var bar = new Bar { BarInfo = string.Concat(foo.Size, " - ", foo.Name) };

    return bar;
}

The above code simply concatenates both properties of our Foo object and sets Bar's BarInfo property with the result.

MSDN says that the operator should be defined on the source type, although it works well if you define it on the target type. Also, it states that you should only use implicit conversions for user-defined types like this if you're absolutely sure that no exceptions may be thrown. If there's too much data transformation, and you may eventually get an exception, then it advises you to use explicit conversions instead.


Expliciting it

Let's say we have a Foo type, which already has an implicit conversion to a Bar type. But now there's this new BigFoo type for which we want to convert our Foo. A Foo needs to have a size of at least 10 to be considered a BigFoo. So what we want to do is:

var foo = new Foo
{
    Size = 10,
    Name = "Foo"
};

BigFoo bigFoo = (BigFoo)foo;

And to enable such code, we define an explicit operator between the two types on the Foo class:

class Foo
{
    public int Size { get; set; }
    public string Name { get; set; }       
        
    public static explicit operator BigFoo(Foo foo)
    {
        if (foo.Size < 10)
        {
            throw new InvalidCastException("Foo is not big enough to be a BigFoo!");
        }

        var bigFoo = new BigFoo { Name = foo.Name };

        return bigFoo;
    }
}
I'd rather read the above conversion code examples as they are then reading code that looks like this:
var foo = new Foo
{
    Size = 10,
    Name = "Foo"
};

var bigFoo = Foo.TryConvertToBigFoo(foo);
var bar = Foo.ConvertToBar(bar);

Monday, December 16, 2013

The Builder pattern

The builder pattern is an object construction pattern that is usually used to handle complex objects creation/initialization. A very good sign that it could be applied is when you start creating lots of constructors, or when your single constructors has lots of parameters, that is because you need the object to be constructed and returned in a state that you can actually use it.


The builder pattern also relies on constructing the object step-by-step, by method calls. Consider making a pizza for example. You first pour the tomato sauce on the dough, then you add cheese, pepperoni and olive oil. Then you bake it. Can you see the steps? If we were to create a pizza with a single constructor, we'd have something like this:

public Pizza(Dough dough, TomatoSauce sauce, Cheese cheese, Pepperoni pepperoni, OliveOil oil)

What if we'd actually want different toppings on the pizza? For example, instead of pepperoni, I'd like to have some sausage on top of the cheese, and I'm not a fan of olive oil. We'd then create another constructor overload for my pizza, right?

public Pizza(Dough dough, TomatoSauce sauce, Cheese cheese, Sausage sausage)

But now I want pepperoni, sausage AND some mushrooms! I think you can already see where this is going: we'd have a different constructor for each set of toppings we'd like on our pizza.

The pizza example is a classic one. With the builder pattern, using a builder object, I can make a pizza with as many toppings as I want! I can also chose whether I want olive oil on it or not.

We then have our pizza, which now has a list of toppings, instead of individual properties for each one of them:

public class Pizza
{
    public Pizza()
    {
        Toppings = new List<Topping>();            
    }

    public Dough Dough { get; set; }
    public TomatoSauce TomatoSauce { get; set; }
    public List<Topping> Toppings { get; set; }
    public bool HasOliveOil { get; set; }
}


Now we can easily implement our builder in a way that it'll be able to make whatever pizza we want:


public class PizzaBuilder
{
    private Pizza Pizza { get; set; }

    public PizzaBuilder()
    {
        Pizza = new Pizza();
    }

    public PizzaBuilder WithThinDough()
    {
        Pizza.Dough = new Dough { Type = DoughType.Thin };

        return this;
    }

    public PizzaBuilder WithThickDough()
    {
        Pizza.Dough = new Dough { Type = DoughType.Thick };

        return this;
    }

    public PizzaBuilder WithFlavoredTomatoSauce()
    {
        Pizza.TomatoSauce = new TomatoSauce { Type = TomatoSauceType.Flavored }; 

        return this;
    }

    public PizzaBuilder WithTomatoOnlyTomatoSauce()
    {
        Pizza.TomatoSauce = new TomatoSauce { Type = TomatoSauceType.TomatoOnly };

        return this;
    }

    public PizzaBuilder WithOliveOil()
    {
        Pizza.HasOliveOil = true;

        return this;
    }

    public PizzaBuilder WithTopping(Topping topping)
    {
        Pizza.Toppings.Add(topping);

        return this;
    }

    public Pizza Bake()
    {
        return Pizza;
    }
}


Notice that I left the whole responsibility of creating the tomato sauce and dough to the builder, as oppose to how I implemented how the toppings are added. I also created a property for the two first instead of creating sub-types for them. There's no real reason for this, they are just implementation details.


Just imagine now that for each one of the toppings we'd have a subclass. So we'd for example have a class called Sausage which extends the Topping class.

class Sausage : Topping
{
    // [...]
}

To get the toppings, I'll just create a class called Toppings which has a set of properties representing each one of the toppings. We could even apply the factory pattern in it.

After having all of these classes, we could then use the builder like this:

var pizzaBuilder = new PizzaBuilder();

var pizza = pizzaBuilder.WithThickDough()
                        .WithFlavoredTomatoSauce()
                        .WithTopping(Toppings.Mozzarella)
                        .WithTopping(Toppings.Sausage)
                        .WithTopping(Toppings.Onion)
                        .WithTopping(Toppings.Mushroom)
                        .WithOliveOil()
                        .Bake();


It's really easier to make pizza now, huh?

Now to forget about pizza and get back to our world, just imagine yourself building a complex XML document by taking advantage of the builder pattern. I bet it wouldn't be that much of a hard task.

Monday, November 11, 2013

Introduction to the SysOperation framework

I'll probably turn this into a series of posts, but for now, I'll just demonstrate the basics of the SysOperation framework.


The SysOperation Framework, initially called Business Operation Framework, seem to be the new substitute of the RunBase framework. As such, it allows you to perform operations that require parameters from the user, it allows you to set the operations to be executed in batch, or in a new asynchronous way, or in a synchronous manner. The great thing is that it simplifies the pack / unpack of variables that was pretty nasty in the RunBase framework, taking advantage of the Attributes feature, introduced with AX 2012.


So to get started, we must understand that the SysOperation framework works in a way that's close to the Model-View-Controller (MVC) pattern.
The key objects here are:

  • Data Contract:

    The data contract is the model class in which we define which attributes we need for our operation, commonly set as parameters by the user in a dialog. It's nothing more than a model class with a few attributes in it. We can define a SysOperation Data Contract class simply by adding the DataContractAttribute attribute to its declaraion. Additionally, if we want a set of methods to be available to us, we can also extend the SysOperationDataContractBase base class. With this class, we can define how our basic dialog will look like to the user. We can define labels, groups, sizes and types of the parameters.
  • UI Builder:

    The UI builder class is actually an optional class for the SysOperation framework, which kind of acts as the view part of the pattern. You should only use it if you want to add some extra behavior to the dialog that AX constructs dynamically for you. If you are perfectly happy with the dialog AX shows you when you run your operation, you shouldn't worry about this class. To create a UI Builder, you should extend the SysOperationAutomaticUIBuilder class. It will provide you a set of methods to work with the dialog's design, but we usually add extra behavior or customize a lookup inside the postBuild method.
  • Controller:

    The controller class has greater responsibility than the others. As the name suggests, it is the class that orchestrates the whole operation. The controller class also holds information about the operation, such as if it should show a progress form, if it should show the dialog, and its execution mode - asynchronous or not. To create a controller class you should extend the SysOperationServiceController, which will give you all of the methods you need.
  • Service:

    There are some who put the business logic on controller classes so that they also perform the operation itself. I'm particularly not a big fan of that, it's too much responsibility for a single class! The programmers who created the SysOperation framework probably think the same, and they have made a way to separate the operation. You can create a service class! The only thing you have to do is extend the SysOperationServiceBase class and you're good to go. This class is the one that should contain all the business logic. When constructing your controller, you will indicate which class holds the operation that the controller will trigger, I'll demonstrate it later.

So this was a brief explanation in my own words of how the SysOperation currently works. For more information, you can also download the official Microsoft whitepaper here.

Now on to the code.


SysOperating it


To define our Model, or our DataContract, all we have to do is create a class, with each of the values created as the class' fields, and parm methods, which will be our "properties". Each field that we want to pack and unpack during the execution of the operation has to have its parm method decorated with the DataMemberAttribute attribute. If we don't add that attribute, the value for that field won't be packed to the server, and will not be initialized when you try to access it on the service class. Additionally, parm methods without the attribute will not have its field displayed on the default dialog.

So for example, consider the following model class:

[DataContractAttribute]
class SysOperationDemoDataContract
{
    Name            name;
    BirthDate       birthDate;

    MonthsOfYear    monthThatWontBeSerialized;
}

[DataMemberAttribute]
public BirthDate parmBirthDate(BirthDate _birthDate = birthDate)
{
    birthDate = _birthDate;

    return birthDate;
}


[DataMemberAttribute]
public Name parmName(Name _name = name)
{
    name = _name;

    return name;
}

public MonthsOfYear parmMonthThatWontBeSerialized(MonthsOfYear _monthThatWontBeSerialized = monthThatWontBeSerialized)
{
    monthThatWontBeSerialized = _monthThatWontBeSerialized;

    return monthThatWontBeSerialized;
}

When we run a Controller that uses the above class as a DataContract, the following dialog is automatically constructed, without the fields that do not have the DataMemberAttribute. As you can see, our field monthThatWontBeSerialized wasn't even added to the dialog:




So after easily defining our model, which is a class that will store all of the values that we will need from the user - or not - for our operation, we can define our service.

To define our service class and have it called by the SysOperation framework, we must define a method that receives our data contract as a parameter. So for this demo, I have defined the following class:

class SysOperationDemoService extends SysOperationServiceBase
{
}

public str performDemo(SysOperationDemoDataContract _contract)
{
    str info = strFmt('%1 was born in %2', _contract.parmName(), _contract.parmBirthDate());

    info(info);

    return info;
}


It doesn't do much. It takes what the user has typed in the dialog and displays it on the Infolog. In a real scenario, this class could either contain the business logic itself, or just interact with other classes that contain it. I personally rather have the business logic in other classes, because by pattern, this class should always have the "Service" suffix. I'll talk more about naming conventions for the SysOperation later.

So we have our Model, we have our service. What about our controller?

The controller class has a few key methods like the RunBase framework, that you should be very familiar with, which are:

  • main
  • construct
  • new
  • validate
  • run


Their names are self explanatory, and if you are a little familiar with the RunBase framework you'll have no problem getting over them. I put the new method in that list because the new method of the base SysOperationServiceController class receives two strings as parameters, which are the name of the class and the method of the service to be executed. There is a neat method called initializeFromArgs which sets these values on the controller after it's constructed, given a correctly intialized Args object. This method allows you to use it with menu items, I'll blog about it later. Anyway, for this example we'll override the new method on our controller.

I've also put the construct method on the list. As a general good practice, your controller should have a public static method called construct, which will do all the dirty constructing (duuh) work. Additionally, you can override the new method and set it as a protected method, so that anyone who wants to use your controller will have to call the construct method.


So here's how I'll define our sample controller:

class SysOperationDemoController extends SysOperationServiceController
{
}

protected void new()
{
    // This tells the controller what method it should execute as the service. In this case, we'll run SysOperationDemoService.performDemo()
    super(classStr(SysOperationDemoService), methodStr(SysOperationDemoService, performDemo), SysOperationExecutionMode::Synchronous);
}

public static SysOperationDemoController construct()
{
    SysOperationDemoController      controller;

    controller = new SysOperationDemoController();

    controller.parmShowDialog(true); // Actually the default value
    controller.parmShowProgressForm(false);

    return controller;
}

public static void main(Args _args)
{
    SysOperationDemoController controller;

    controller = SysOperationDemoController::construct();

    controller.startOperation();
}

protected boolean validate()
{
    SysOperationDemoDataContract    contract;
    boolean                         ret = true;
    
    contract = this.getDataContractObject();
    
    if (contract.parmBirthDate() > DateTimeUtil::date(DateTimeUtil::addYears(DateTimeUtil::utcNow(), -18)))
    {
        // Failing the validate will not close the dialog, and the user will have another chance of inputting the correct values
        ret = checkFailed('The user is underage!');
    }
    
    return ret;
}

public void run()
{
    info('Run method has been called');
    
    super();
}

protected ClassDescription defaultCaption()
{
    // This will be the dialog's caption
    return 'SysOperation demo';
}

So as you can see we define which method will be executed as the service on the new method.
The construct method does the dirty work, setting some properties on the controller. The validate then checks if the user is at least 18 years old. If the validate fails, the user has another chance of setting the correct values on the dialog. Also, as a tip, I've set the dialog's caption by overriding the defaultCaption method. As for the run method, I've only overwritten it so that you can see the execution flow, which is:

>> main
>> construct
>> validate
>> run

Draw a sequence diagram in your head. :)


With the three classes that I have described here, you can actually run a simple SysOperation framework demo. You can do this by simply opening the controller class and pressing F5.


Here's some tips that can save you some time:

  • You should generate incremental IL for every change on any of the classes from the SysOperation framework. It won't take long, and unfortunately, it's necessary
  • When you start getting odd behaviors, specially when you change something on your DataContract and it doesn't reflect on your dialog, you should clean the usage cache. You can do this by clicking on Tools > Options > Usage data > Reset
  • You can debug SysOperation services if your Controller class' execution mode is either Synchronous or Asynchronous, when you've unchecked the option to execute business operations in CIL. You can get more info on executing business operations in CIL here.


As I've mentioned, the UI Builder class allows us to completely customize the dialog which is constructed for us. Since I'll probably turn this into a series of posts, I'll demonstrate this over the next posts.


Even though it's fairly easy and simple to understand, I must confess that I think it requires too much code infrastructure to perform some simple tasks. It feels strange having to write at least 3 classes to perform a simple delete operation that requires some extra logic or validation, for example. Still, I'd rather have to do so instead of having to control the dirty pack / unpack pattern of the RunBase framework.

Monday, September 30, 2013

Any unnecessary code is evil code

I bet you have already gone through a situation where you added lines of code just because it was easy enough or because you were already changing something on the same part of the program.

Well, don't.



No matter how easy it is to do something, no matter how fast, if you don't have a real - and good - reason to do it, don't.

Here are some questions you can ask yourself before implementing something, some that I keep asking myself all the time:

  • Does this add value to the product?

    Good code or features are the one that add value to the product as a whole. Just because a feature was well developed and works well doesn't mean that it adds value to the product.
    A feature that adds value to the product is something that the users also see as a value. How many times did you see a feature being added to the backlog, implemented and shipped just because your manager thought it was good, but after being shipped it ended up not being used at all?


  • Do the users really need this feature?

    Even if it does add value to the product, it may add little value to it. So the question is: do we really want to implement it?
    For example, to perform something the users have to click 5 times. You have the chance to reduce that from 5 clicks, to 3 clicks. But none of your users have ever complained about this, none of them have ever said anything about having to click too much to perform something. Do you really have to spend time improving that?


If the answer to both of the questions above is no, we can consider not implementing it.

But if after that you still want to implement it, ask yourself these two other questions:

  • What is the impact of this change, for your daily work?

    Always be very aware that even the smallest time you will spend on a change - even debating it - could be spent on a different matter. Even if you don't implement something you'll have to spend some time debating and agreeing on not doing so, and this takes time. Always remember that the time you spend on any feature could be spent on any other feature, one that adds more value to the product.


  • What bugs can this change generate?

    This is also a very important question. This is, in fact, what this post is all about. Giving a short answer to it: you may introduce a bug with code that you didn't need to write in the first place! Let's consider the example of the clicks again. What if, by reducing the number of clicks the user has to perform to achieve something, the programmer forgets to initialize something? That is awful from the user's point of view. The users had some process working with 5 clicks, and all of a sudden it got short - but it also doesn't work anymore. And guess what? He didn't request this change.


If you got bad answers for these questions, you will almost certainly not implement it all. And it's actually OK. It's all about delivering what adds value to the product, really.

Unnecessary code also goes into your ALM process, meaning you will also have to test it, write unit tests for it, and maintain it. All of these tasks take time from the programmers that could be working on something that really adds up to the product. Do you see the size of the problem work you have created, for something that will have no good response from your user base?

And don't forget that the next person who maintains these evil lines of code will spend some time trying to understand, and possibly fixing a bug or a unit test that was failing. All of that work for code that shouldn't have been added in the first place.

As I've said before: if you don't absolutely have to write code for something, don't.

Thursday, September 26, 2013

"But what if I had to test this?"

It's a fact that developing software using test driven development (TDD) techniques assures a higher quality than other conventional techniques.

TDD consists of making the developer start off with a test, and then write code to make the test pass, repeating this process in cycles. This makes us think about the best design for the smallest unit in code: methods.

Since you have to write the code that consumes your method before writing the actual method, you'll always end up with a simplistic, easy-to-use version of it. It's like putting ahead what you expect from your code, and then writing it. This often tends to push you to the best design: smaller, clearer methods with a single responsibility, fewer lines of code.

But forget about TDD for now, I'll blog about that later.


The message I'm trying to pass here is not "use TDD" or "write unit tests", but at least pretend that you're doing so! - By the way, you should totally experiment with TDD and PLEASE, DO WRITE UNIT TESTS!





But what if I had to test this?

Those of you who use TDD or just write unit tests will, eventually, change your design to make the testing easier.

But those of you who don't do any of them, you should.


Whenever writing a big fat method with lots and lots of lines of code, think about it. Ask yourself the question: "How would I test this?".


For example, take the following method:

public boolean DoSomething()
{
    var result = from child in this.Father.Children
                 from grandChild in child.GrandChildren
                 where (child.Foo == "Foo" &&
                       grandChild.Bar == "Bar" &&
                       child.Value > 10 &&
                       child.Value < 50 || 
                       grandChild.Amount * 100 < 0) ||
                       (child.Value > 100 &&
                       grandChild.Amount * 765 < 10000 &&
                       (child.Foo == "Not Foo" ||
                       ((int)grandChild.Amount ^ 2) == 3600))
                 group child by new { child.Foo, child.Value } into g
                 select new
                     {
                         Sum = g.Sum(child => child.Value),
                         FooMax = g.Max(child => child.Foo)
                     };

    var firstGroupedChild = result.First();

    if (firstGroupedChild.FooMax != "ZZZ")
    {               
        var correctedGrandChild = new GrandChild();

        correctedGrandChild.Bar = "Corrected grand child";
        correctedGrandChild.Amount += firstGroupedChild.Sum * 1.10;

        correctedGrandChild.InsertOnDatabase();

        DataAccessObject.DeleteFromDatabase(firstGroupedChild.FooMax);

        return true;
    }

    return false;
}
I couldn't even think of a bad name to that!


Now ask yourself: "How do I test this?".
A: Man, you're gonna have a bad time...

If the developer who wrote that code had the exact same question in mind from the very beginning, I'm pretty sure he would have dropped the idea of doing so much stuff - including a complex Linq query - on a single method just right there. Imagine how many Unit Tests you would have to write just to test the minimum of something like that. That is a terribly poorly written method.

If you don't test at all, it's actually acceptable to have something like this, given that you're not too worried about the quality of your product anyway. But you should! Do care about quality! Even if you don't assure it, at least remember that it exists!

Also, be a good guy and think about the fellow developer who maintains this code. He'll sure have a terrible time trying to find out just why the hell one of the "child" objects was not found on the first query, and not summed up.


Now imagine if we could translate the method above to the following:

var children = Father.GetChildrenThatSatisfySomeCondition();

var groupedResults = Child.GroupBySomeCondition(children);

var childFooMax = groupedResults.Max(child => child.Foo);

if (childFooMax.Foo!= "ZZZ")
{
    var correctedGrandChild = GrandChild.GetNewCorrectedFromChild(childFooMax);
    
    DataAccessObject.PerformChildCorrectionWithGrandChild(childFooMax, correctedGrandChild);

    return true;
}

return false;


Ooooooh! It all makes sense now! Now I can even understand the logic flow of the things I have to test! I could totally write Unit Tests for each one of the extracted methods now, because they all seem to be small, cohesive, and have a single responsibility.

And that would have been the first choice of design if the developer had thought about testing it before, or while he was writing it.


Code quality - and specially the semantics - matter, always.

Thursday, September 19, 2013

Calling methods on a caller Dynamics AX form

To call methods on a caller form from another form or a class for example, you have to fetch the caller from the args object, keep it as an Object and just then you can call methods in it.

You have to keep it as an Object like the caller method returns it to you, because then the compiler allows you to call methods in a dynamic way. This means that there will be no compile-time checking for the method that you are trying to call, as it happens with any object of type Object in AX, so if you try to call a method that doesn't exist on the form, you'll get a run-time error.


Here's some example code:

Object caller = _args.caller(); 

    // Or if you're in a form:
    // caller = element.args().caller();

    caller.someMethodOnTheForm();


And just to add some defensive code so that you can avoid getting a run-time error, you could add the following validations to the same piece of code:

Object caller = _args.caller();

    if (caller is FormRun && formHasMethod(caller, identifierStr(someMethodOnTheForm)))
    {
        caller.someMethodOnTheForm();
    }

Now you're also checking if the caller is in fact a form, and also if it has the method you're trying to call.