Wednesday, August 26, 2009

Firefox is DevExpress friendly

Did you now that there is a DevExpress search engine provider for FireFox?

image

http://mycroft.mozdev.org/search-engines.html?name=devexpress

Just install that beauty and every time you want to search something by using this excellent post

Master the Firefox search engine bar with keyboard shortcuts

use your keyboard press some keys and you are searching DevExpress

Technorati Tags: ,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Tuesday, August 25, 2009

ModelArtifact AdditionalViewControlsProvider And MasterDetail videos republished

Since I got many complaints about the low resolution of my videos I am on a search for a better video hosting service than YouTube.

Robert suggested to use Silverlight service at Blogger Video embedding resolved but this one looks the same as YouToube. After spending some more time on researching on this I came across http://blip.tv/ excellent hosting service

To get an idea how good they are I suggest you read their FAQs

  • They accept almost all kinds of  Videos
  • They are free
  • They do not change the video after uploading
  • The customization of the video playback controls is unlimited.
  • You can configure almost anything on their well design interface

I am going to use that excellent service to republish my videos

So if you want to see those videos again in good resolution this time go to

Bend Xaf Applications with Model Artifact State Module 

and

Implementing Master-Detail with No Code

and use the full screen button on the bottom right corner

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Blogger Video embedding resolved

I recently most ModelArtifactState and with the congratulations for it I got many complains about the video quality.

This is because I host my videos to YouTube which has many drawbacks

  • The actual resolution of YouTube videos is limited to 320 x 240 pixels.
  • The video suffers from strong compression (limited to 250 kbps).
  • The YouTube watermark may overlap your video.
  • The customization of the video playback controls is limited.

But where to host my files? Little more googling and I came to Google sites that offer 100Mb / per site and 11mb per file limits. I think that is enough

After talking to a flash guru like Kostas Efimeros I got the info I need.

I should convert my videos to FLV format using for example SUPER which is a free FLV video encoder and use JW FLV Player to stream them from Google sites

ps: In order JW FLV Player to work correctly your urls query string should be null

Technorati Tags: ,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Friday, August 21, 2009

Xaf tip # 4

This is my 4th post on my Xaf tips series

Runtime Member creation on TypesInfo and XPDictionary

When you are developing modules and need to generate runtime member you should be carefull which method you choose because the following is valid always

Assert.IsNull(XafTypesInfo.Instance.FindTypeInfo(typeof(Country)).CreateMember("TestMember", typeof(string)));

and this one not

Assert.IsNull(XafTypesInfo.XpoTypeInfoSource.XPDictionary.GetClassInfo(typeof(Country)).CreateMember("TestMember",typeof(string)));

So to test my sayings create a new Xaf Application add a controller and call

public override void CustomizeTypesInfo(ITypesInfo typesInfo){
    base.CustomizeTypesInfo(typesInfo);
    var memberInfo = XafTypesInfo.XpoTypeInfoSource.XPDictionary.GetClassInfo(typeof(Country)).CreateMember("TestMember",typeof(string));
}
memberInfo  in this case is not null

but when

public override void CustomizeTypesInfo(ITypesInfo typesInfo){
    base.CustomizeTypesInfo(typesInfo); 
    var memberInfo = XafTypesInfo.Instance.FindTypeInfo(typeof(Country)).CreateMember("NewProperty", typeof(String));

memberinfo is null!!! It is going to work only if you add Country to your AdditionalBusinessClasses collection

like

image

Did you know that?

So typesInfo knows only about your application BussinessClass and XPDictionary about any persistent class

Which one to use ? I would suggest the XPDictionary one cause XPDictionary can also add runtime non persistent member like collections .

I have also write a small helper class to help me add a runtime association with less code

public static class TypesInfoExtensions{
    public static bool CreateCollection(this ITypesInfo typeInfo, Type typeToCreateOn, Type typeOfCollection,
                                        string associationName, XPDictionary dictionary){
        if (typeIsRegister(typeInfo, typeToCreateOn)){
            XPClassInfo xpClassInfo = dictionary.GetClassInfo(typeToCreateOn);
            XPCustomMemberInfo member = xpClassInfo.CreateMember(typeOfCollection.Name + "s", typeof (XPCollection),
                                                                 true);
            member.AddAttribute(new AssociationAttribute(associationName, typeOfCollection));
            return true;
        }
        return false;
    }

    private static bool typeIsRegister(ITypesInfo typeInfo, Type typeToCreateOn){
        return typeInfo.PersistentTypes.Where(info => info.Type == typeToCreateOn).FirstOrDefault() != null;
    }

    public static bool CreateBothPartMembers(this ITypesInfo typesInfo, Type typeToCreateOn, Type otherPartType,
                                             XPDictionary dictionary){
        return CreateBothPartMembers(typesInfo, typeToCreateOn, otherPartType, Guid.NewGuid().ToString(), dictionary);
    }

    public static bool CreateBothPartMembers(this ITypesInfo typesInfo, Type otherPartType, Type typeOfMember,
                                             string associationName, XPDictionary dictionary){
        bool members = CreateMember(typesInfo, otherPartType, typeOfMember, associationName,dictionary);
        if (members)
            members = CreateCollection(typesInfo, typeOfMember, otherPartType, associationName, dictionary);
        return members;
    }

    public static bool CreateMember(this ITypesInfo typesInfo, Type typeToCreateOn, Type typeOfMember,
                                    string associationName,XPDictionary dictionary){
        if (typeIsRegister(typesInfo, typeToCreateOn)){
            XPClassInfo xpClassInfo = dictionary.GetClassInfo(typeToCreateOn);
            XPCustomMemberInfo member = xpClassInfo.CreateMember(typeOfMember.Name, typeOfMember);
            member.AddAttribute(new AssociationAttribute(associationName));
            return true;
        }
        return false;
    }

    public static bool CreateBothPartMembers(this ITypesInfo typesinfo, Type typeToCreateOn, Type otherPartMember, XPDictionary xpDictionary, bool isManyToMany, string association){

        bool collection = CreateCollection(typesinfo, typeToCreateOn, otherPartMember, association, xpDictionary);
        if (collection)
            collection = CreateCollection(typesinfo, otherPartMember, typeToCreateOn, association, xpDictionary);
        return collection;
    }

    public static bool CreateBothPartMembers(this ITypesInfo typesinfo, Type typeToCreateOn, Type otherPartMember, XPDictionary xpDictionary, bool isManyToMany){
        Guid guid = Guid.NewGuid();
        return CreateBothPartMembers(typesinfo, typeToCreateOn, otherPartMember, xpDictionary,isManyToMany,guid.ToString());
    }
}

so now you can create a many to many association between your Country and Customer classes with code like

XafTypesInfo.Instance.CreateBothPartMembers(typeof (Customer), typeof(Country),
XafTypesInfo.XpoTypeInfoSource.XPDictionary, true);

one note here the 3rd parameter could be removed if Devexpress implements this suggestion

so the above code could be written like

XafTypesInfo.Instance.CreateBothPartMembers(typeof (Customer), typeof(Country), true);

ps:You may wonder why i use the typeIsRegister method on my extensions for the answer my friends read this Xaf tip #2

Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, August 17, 2009

Bend Xaf Applications with Model Artifact State Module

How many times have you said “What a great pattern MVP is!!!” Look for example how is implement the hint engine of main Xaf demo. I will try to explain that implementation.

Controllers

There is a windowcontroller called AdditionalInfoController and from it 2 controllers derive WebShowAdditionalInfoController and WinShowAdditionalInfoController.

What they do? they enable inserting any kind of control as the first control of a view. They are the engine, they implement a behaviour and they also serve as the Observer design pattern

Observer pattern: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

I am going to refactor the code from the main demo and create 3 new modules for eXpand

eXpand.ExpressApp.AdditionalViewControlsProvider
eXpand.ExpressApp.AdditionalViewControlsProvider.Win
eXpand.ExpressApp.AdditionalViewControlsProvider.Web

So any controller needs to use the hint engine all it has to do is implement IAdditionalViewControlsProvider interface and register to the engine at its activation events look for example the controllers that are resposible for sawing the hint panel

for windows

public partial class WinControlsController : ViewController, IAdditionalViewControlsProvider
{
    protected override void OnActivated()
    {
        base.OnActivated();
        Frame.GetController<WinShowAdditionalViewControlsController>().Register(this, View, Frame);
        
    }
    protected override void OnDeactivating()
    {
        Frame.GetController<WinShowAdditionalViewControlsController>().Unregister(this);
        base.OnDeactivating();
    }
    public object CreateControl()
    {
        return new WinHintPanel();
    }

    public AdditionalViewControlsProviderDecorator DecorateControl(object control)
    {
        return new WinHintPanelDecorator(View, (HintPanel)control);
    }
}

and for web

public partial class WebControlsController : ViewController, IAdditionalViewControlsProvider
{
    protected override void OnActivated()
    {
        base.OnActivated();
        Frame.GetController<WebShowAdditionalViewControlsController>().Register(this, View, Frame);
    }
    protected override void OnDeactivating()
    {
        Frame.GetController<WebShowAdditionalViewControlsController>().Unregister(this);
        base.OnDeactivating();
    }

    public object CreateControl()
    {
        return new WebHintPanel();
    }

    public AdditionalViewControlsProviderDecorator DecorateControl(object control)
    {
        return new WebHintPanelDecorator(View, (HintPanel) control);
    }
}

and now we can decorate any baseobject with a AdditionalViewControlsAttribute like

[AdditionalViewControls("Message for all customer listview",ViewType.ListView,"PropertyNameWithTextToDisplayUnderText")]
public class Customer : BaseObject
{
    
    public string PropertyNameWithTextToDisplayUnderText
    {
        get
        {
            return "another message";
        }
        
    }
}

and have a message that will be displayed to all Customer’s list views for both Web and Win applications. AdditionalViewControls attribute has some parameters that help controlling the visibility, the text of the message or the control to display that message.

[AdditionalViewControls("Message for all customer listview", ViewType.ListView, AdditionalViewControlsProviderPosition.Bottom, typeof(HintPanel), typeof(WinHintPanelDecorator))]
public class Customer : BaseObject
{

image

Nice feature eh? what do you think?

I think its nice but I also think that is very limited, cause I cannot change its visibility according a business rule. For example I would like to display a hint panel only for Customers that live in Paris or only to a named view with id Customer_Grouped_By_Name_ListView or to a Customer Nested listview or to a user that has permissions to do so or … etc you get my point here

To accomplish such scenario that is to enable or disable controllers and actions against a bussiness rule I have develop ModelArtifactState module

so together with AdditionalViewControlsProvider module I will also release the following  modules

eXpand.ExpressApp.Validation
eXpand.ExpressApp.ModelArtifactState
eXpand.ExpressApp.ModelArtifactState.Win

Video 1 

Video 2 
/p>

Ps: Remember Favor composition over inheritance? Do you see that if you apply that principle is going to make your life with ModelArtifactState module easier?

Imagine having 2 controllers A and B. B inherits A. Now you want to use ModelArtifactState to make B conditional, but since it inherits A that behavior(conditionality) is going to be applied to A as well. If you used composition over inheritance you could change the behavior to any of A or B controllers

You can find the above modules as part of eXpand hosted at google code

Ps (Again): My good friend Martin Praxmarer has join eXpand team and contribute its wizard module so now eXpand is wizard Driven, I will post more on that on a later post. So another additional module for eXpand is

eXpand.ExpressApp.WizardUI.Win

I am going to wait DevExpress to release its final 9.2.x version to release any precompiled version of eXpand but you can find eXpand 0.0.0.10 at google code trunk

http://code.google.com/p/expandframework/

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Thursday, August 13, 2009

Implementing Master-Detail with No Code

 

eXpand already has this scenario enabled for windows forms applications. What you have to do is set 2 attributes and you are done!!! You have force your grid to display a child grid view

image

image

Video1

eXpand is hosted at http://code.google.com/p/expandframework/

Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Sunday, August 9, 2009

Favor composition over inheritance

There is a software design principle that states “Favor composition over inheritance

Inheritance is a cool way to change behavior. But we know that it's brittle, because the subclass can easily make assumptions about the context in which a method it overrides is getting called. There's a tight coupling between the base class and the subclass, because of the implicit context in which the subclass code I plug in will be called. Composition has a nicer property. The coupling is reduced by just having some smaller things you plug into something bigger, and the bigger object just calls the smaller object back. From an API point of view defining that a method can be overridden is a stronger commitment than defining that a method can be called.

That Principe my friends is valid for Xaf also. So overriding other controllers should be considered a bad practice and your controllers should be design to expose all functionality needed to be able to be composed by a statement like this

protected override void OnActivated()
{
    base.OnActivated();
    Frame.GetController<MyController>().MyCustomEvent+= (sender, args) => DoSomething(args);
}

form any other controller thus achieving all the above.

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, August 3, 2009

eXpand 0.0.0.9 is out

 

See what's fixed here

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

and as always you can see what has been changed here

http://code.google.com/p/expandframework/wiki/NDepend_Reports

Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Sunday, August 2, 2009

Xaf tip #2

Just come back from my short holidays this year and I am feeling very relaxed. So I though I should continue my Xaf tips series as I encounter them in my every day work.

Be carefull of DevExpress.ExpressApp.DC.TypesInfo.FindTypeInfo method

imagine any kind of conflict you like taking into account that a new table named Person is going to be created at your db with the following lines

public override void CustomizeTypesInfo(ITypesInfo typesInfo)
{
    base.CustomizeTypesInfo(typesInfo);
    ITypeInfo personClassInfo = typesInfo.FindTypeInfo(typeof(Person));
    if (personClassInfo != null)
    {
        IMemberInfo personFullNameMemberInfo = personClassInfo.FindMember("FullName");
        var persistentAliasAttribute = personFullNameMemberInfo.FindAttribute<PersistentAliasAttribute>();
        if (persistentAliasAttribute == null)
            personFullNameMemberInfo.AddAttribute(new PersistentAliasAttribute("FirstName + MiddleName + LastName"));
    }
}

but not with those bellow which are almost the same

public override void CustomizeTypesInfo(ITypesInfo typesInfo)
{
    base.CustomizeTypesInfo(typesInfo);
    ITypeInfo personClassInfo = typesInfo.PersistentTypes.Where(info => info.Type == typeof(Person)).SingleOrDefault();
    if (personClassInfo != null)
    {
        IMemberInfo personFullNameMemberInfo = personClassInfo.FindMember("FullName");
        var persistentAliasAttribute = personFullNameMemberInfo.FindAttribute<PersistentAliasAttribute>();
        if (persistentAliasAttribute == null)
            personFullNameMemberInfo.AddAttribute(new PersistentAliasAttribute("FirstName + MiddleName + LastName"));
    }
}
Maybe FindTypeInfo name was not chosen correctly to express what it really does. Anyway I am happy that I know that now
Technorati Tags: ,,

Subscribe to XAF feed
Subscribe to community feed

DiggIt!