Mapping [Entity] - controler, model, view etc

Feb 17, 2010 at 8:43 AM

Hello Radim

sorry, that only i am disturb you :)

but.
1) I have got problem:
    Sometimes i need to by [entity type] determinate [model type], [controler type], [facade type], [dao type] etc
    Current mapping (Concrete type factory) provide possibility to get from more complex types - more simple
    (EX: Controler could provide: model, facade, entity, etc), Model could provide -entity etc, facade could provide entity, dao etc)

   Is there "concept"/way to get by "more simple type" more complex ?

2). Maybe i am wrong, "smart binder" can't bind "properties with [Self entity type]".
    it could take result for propertis with types from "system" namespace and "simple lists"
    WHY? why i couldn't have property with derived type from [Persistent] (i can restore property value b[ID]). Am i wrong?
    Why that functionality doesn't exist in standard smart binder?

 

regards, Anatoliy

 

Coordinator
Feb 18, 2010 at 7:19 AM

Hi Anatoliy

Shame is that you are only one who is asking ...

1) I am not sure if I do understand you. Factory in Catharsis is able to instantiate any type which is decorated with concrete type attribute. But this one type only. The tree of dependent object must be instantiated manually  - usually using the service locator pattern, to do it lazily.

2) Well, The smart binder is targeted for ValueTypes and string. That's all. BUT, that was what we decided, that is enough. The Smart binder is in fact extension of the built in MVC binder. And that means: you can create your own and extend functionality

Have a nice day

Radim Köhler

 

Feb 18, 2010 at 1:20 PM

Hello Radim.

  1. By [service locator pattern] you mean Unity or Castle (or others). That is why, when first time I have seen Catharsis, I was surprised about this.

(Why it use [self] factory to provide code injections, think it is bottle neck of the platform)

  1.  Yes I can make own binder, but is better to already have smart one, which to do this automatically.

Because persistent entities is standard for Catharsis, that is why is good to have parser for [PersistentEntity]  property type and list of [PersistentEntity]  property type.

It is understandable that you are “constructor-architect” of the platform. It is just suggestion from [one independent person].

Look like Catharsis is good start point to build self platform (because a lot of things needs to be done extra), but will be much better if it already contains those things.

Thanks for the explanation, best regards

Anatoliy


From: Radim [mailto:notifications@codeplex.com]
Sent: Thursday, February 18, 2010 10:20 AM
To: nocher@mail.ru
Subject: Re: Mapping [Entity] - controler, model, view etc [Catharsis:85621]

From: Radim

Hi Anatoliy

Shame is that you are only one who is asking ...

1) I am not sure if I do understand you. Factory in Catharsis is able to instantiate any type which is decorated with concrete type attribute. But this one type only. The tree of dependent object must be instantiated manually - usually using the service locator pattern, to do it lazily.

2) Well, The smart binder is targeted for ValueTypes and string. That's all. BUT, that was what we decided, that is enough. The Smart binder is in fact extension of the built in MVC binder. And that means: you can create your own and extend functionality

Have a nice day

Radim Köhler

Read the full discussion online.

To add a post to this discussion, reply to this email (Catharsis@discussions.codeplex.com)

To start a new discussion for this project, email Catharsis@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Feb 18, 2010 at 1:51 PM

Hi Anatoliy

Well, firstly to the binder. It is designed the way, that it could fill any valuetype + string property from the request. The rest is upon you, because any other property is reference type. That mean that smart binder should be really very very smart to findout, that selected combobox value e.g. '4' means the currency entity 'EURO'.

For this purposes, there is a controller OnBindModel method, to be overrided. there you should check if the Form contains the currency id (selected from combo) and ask the CurrencyFacade to GetById the currency entity. If this will suceed, append it to the entity.Currency.

This is the right way, how to bind the reference type of the IPersistent type.

 

And now to the Object instance factory.

The Catharsis biggest advantage is that is totally indpendent on any other library (except the NHibernate). Layers are aboslutely independent (there are even no reference from upper layer to lower one) . The built in factory is smart enough to provide instances for used Interfaces. Therefore you cane easily get the instance of the IUserFacade, by calling the:

FacadeFactory.CreateFacade<IUserFacade>(Messages)

This is the easiest way how to get the instance on the layer, which only reference the interface and not the impelemtning class (to call new UserFacade). This will assure that you will operate only with the IUserFacade exposed properties and methods. No access to public stuff of the UserFacade...

And that's called the Service locator design pattern. It means, that you call factory for getting the instance.

Your suggested frameworks used for Dependency Injection (DI) can be easily introduced to catharsis (just implement IFactory, append its provider to the Project.config ... and you can use Castle, Spring.NET etc.

These frameworks are usually heavy weights. And mostly are used for the DI pattern instead of the Service locator. This pattern creates the objects trees. E.g if your IUserController exposes the property IUserFacade { set; }, It will be also created for you. You do not have to think about calling the Factory.GetInstance().

BUT:

There is a down side of perfromance. This is another story...

Anyhow, this is upon you, which way you will go. The Catharsis framework does not need any external library to be working and really very good in performace. And that's what we need.

Enjoy the Catharsis and keep on asking! :)

Radim Köhler

Feb 19, 2010 at 8:13 AM

Hi Radim,

Well, firstly to the binder. It is designed the way, that it could fill any valuetype + string property from the request. The rest is upon you, because any other property is reference type. That mean that smart binder should be really very very smart to findout, that selected combobox value e.g. '4' means the currency entity 'EURO'.

ComboBox case: combobox (by Catharsis model) have same name with one of the property of the current entity (Am i wrong?)

Property has special type (which, by code, current binder is checking). So: Binder knows! that  value e.g 4 it is unique number of the entity ‘Euro’

But now is too hard to extend current binder to get by Entity Type – DAO\Facade objects(To get by ID an entity).
(needs to be apply object injections{Unity} or needs to be rewrite a lot of “basic code”)

For this purposes, there is a controller OnBindModel method, to be overrided. there you should check if the Form contains the currency id (selected from combo) and ask the CurrencyFacade to GetById the currency entity. If this will suceed, append it to the entity.Currency.

Looking good, I will check this possibility. Idea to bind data in the Binder is looking better then current way.

Because in that case for each of new entity developer will need to develop code in one extra place
(Maybe, is better to do this automatically, maybe not? Do you have any suggestion about it, about more automatic work less coding?)

And now to the Object instance factory.

Sounds good, but independents layers could communicate with each others? (because they don’t know how, they independents)

Maybe is good to use Factory too establishing dependencies between [Entity]- [EntityDAO], [Entity]-[entity Facade]

to provide way of automatically works controllers, models, views by small modifications only in the Entity class.

(Maybe I am wrong, and didn’t understand ideas of catharsis, but as for me entity is central point of all)

Something like that I want to have:

(Interesting blocks has been selected)   

namespace Company.Product2.Entity.Customers

{

    /// <summary>

    /// Entity Person.

    /// </summary>

    [Serializable]

    //tabs

    [Tab(Name="tabPersonalInfo",Position=1,Title="Personal Information", Description="content on this TAB should be updated, if customer information has  been changed...")]

    [Tab(Name = "tabRelatedOrders", Position = 2, Title = "Related Orders", Description = "")]

    [Tab(Name = "tabNotImportant", Position = 3, Title = "Extra", Description = "information on this tab is not so important...")]

    //fileds groups

    [Group(TabName = "tabPersonalInfo", Name = "grNameInfo", Position = 1, Title = "Customer Names", Description = "Check the data double time to prevent mistakes in the information")]

    [Group(TabName = "tabPersonalInfo", Name = "grBirthday", Position = 2, Title = "BirthDay", Description = "")]   

    [ConcteteInterface(RelationType.IFacade,”Company.Product2.Common.Business.Customers. IPersonFacade”)]

    [ConcteteInterface(RelationType.IController,”................”)]

    public class Person : Persistent

    {

        [PropertyDescription(Group = "grNameInfo", Title = "Login name", Description = "here should locates uniq. login name",Position=1)]

        [Required()]

        public virtual string Code { get; set; }

        [PropertyDescription(Group = "grNameInfo", Title = "First Name", Description = "",Position=2)]

        [Required()]

        public virtual string FirstName { get; set; }

        [PropertyDescription(Group = "grNameInfo", Title = "Last Name", Description = "", Position = 2)]

        [Required()]

        public virtual string LastName { get; set; }

        [PropertyDescription(Group = "grBirthday", Title = "BirthDay", Description = "", Position = 1)]

        [InputMask("99/99/9999")]

        [Required()]

        public virtual DateTime? BirthDay { get; set; }

        public virtual bool? IsActive{ get; set; }

        [RegularExpression("^[0-9]*")]

        [InputMask("9999999999999999")]

        [Required()]

        public virtual string IdentificationCode { get; set; }

        [PropertyDescription(Group = "tabNotImportant", Description = "put you small coments here")]

        [DataTypeEx(DataTypeEx.Html)]

        public virtual string Description { get; set; }

        [PropertyDescription(Group = "tabRelatedOrders")]

        [DataTypeEx(DataTypeEx.RelatedTable)]

        public virtual IList<Order> Orders { get; set; }

        [PropertyDescription(Group = "tabRelatedOrders")]

        [DataTypeEx(DataTypeEx.RelatedSingleSelect)]       

        public virtual Person Parent { get; set; }

        #region override abstract

        /// <summary>

        /// Provides quick, string description about the 'Person' instance

        /// </summary>

        public override string ToDisplay()

        {

            // This method is often used on View

            // there for provide clear and understandable

            // set of properties (separated by spaces ' ')

            // which will quickly provide information about this instance

            return IDToDisplay + " " + FirstName;

        }

        /// <summary>

        /// Returned value should be handled as business unique key.

        /// Equal method (implemented in Tracked base class) will use it

        /// to compare two Persons

        /// </summary>

        protected override string GetDomainObjectSignature()

        {

            // TODO return the property (or list of properties separated by "|")

            // which will allow to distinguish among entities

            return Code;

        }

        #endregion override abstract

    }

}

BUT: There is a down side of performance. This is another story...

Yes I know, that is why, I prefer to use Unity and as smaller as possible (but sill I don’t want to use it in combination with Catharsis, which yet working perfectly without others object injection tech.)

Yes I know that my and your visions are different and I don’t want that you will take my side.

Just hope you will help me to little bit “extend” catharsis to provide way of quick development, best performance,

flexible entity editing forms.

Best regards ,Anatoliy


From: Radim [mailto:notifications@codeplex.com]
Sent: Thursday, February 18, 2010 4:52 PM
To: nocher@mail.ru
Subject: Re: Mapping [Entity] - controler, model, view etc [Catharsis:85621]

From: Radim

Hi Anatoliy

Well, firstly to the binder. It is designed the way, that it could fill any valuetype + string property from the request. The rest is upon you, because any other property is reference type. That mean that smart binder should be really very very smart to findout, that selected combobox value e.g. '4' means the currency entity 'EURO'.

For this purposes, there is a controller OnBindModel method, to be overrided. there you should check if the Form contains the currency id (selected from combo) and ask the CurrencyFacade to GetById the currency entity. If this will suceed, append it to the entity.Currency.

This is the right way, how to bind the reference type of the IPersistent type.

And now to the Object instance factory.

The Catharsis biggest advantage is that is totally indpendent on any other library (except the NHibernate). Layers are aboslutely independent (there are even no reference from upper layer to lower one) . The built in factory is smart enough to provide instances for used Interfaces. Therefore you cane easily get the instance of the IUserFacade, by calling the:

FacadeFactory.CreateFacade<IUserFacade>(Messages)

This is the easiest way how to get the instance on the layer, which only reference the interface and not the impelemtning class (to call new UserFacade). This will assure that you will operate only with the IUserFacade exposed properties and methods. No access to public stuff of the UserFacade...

And that's called the Service locator design pattern. It means, that you call factory for getting the instance.

Your suggested frameworks used for Dependency Injection (DI) can be easily introduced to catharsis (just implement IFactory, append its provider to the Project.config ... and you can use Castle, Spring.NET etc.

These frameworks are usually heavy weights. And mostly are used for the DI pattern instead of the Service locator. This pattern creates the objects trees. E.g if your IUserController exposes the property IUserFacade { set; }, It will be also created for you. You do not have to think about calling the Factory.GetInstance().

BUT:

There is a down side of perfromance. This is another story...

Anyhow, this is upon you, which way you will go. The Catharsis framework does not need any external library to be working and really very good in performace. And that's what we need.

Enjoy the Catharsis and keep on asking! :)

Radim Köhler

Read the full discussion online.

To add a post to this discussion, reply to this email (Catharsis@discussions.codeplex.com)

To start a new discussion for this project, email Catharsis@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Feb 19, 2010 at 11:21 AM

Hi Anatoliy

Great! Great job you did. There is no general good, right way how to do it. I think, that your approach, if it will work for you, is simply perfect. That's all. Catharsis is intended as a framework, which creates the basic stuff and infrastructure for you. Whatever else you need to use, is upon you.

Probably the best approach would be, create some example. We can then upload it, and provide it as other 'real' usage. No doubt that it could work for someone else as well.

 

Few comments to our ideas about binding:

There is entity. it has value type (plus string) properties, which are gathered from the request. Smart binder is ready to fill the entity's properties, using the user culture (very important). Next step is appending the reference types:

protected override bool OnBindModel()
        {
            var result = base.OnBindModel();
            short id;

            if(Request.Form[Str.Controllers.Color].TryParse(out id))
            {
                var color = ColorFacade.GetById(id);
                if(color.Is())
                {
                    Model.Item.Color = color;
                }
            }

            if (Request.Form[Str.Controllers.Line].TryParse(out id))
            {
                var line = LineFacade.GetById(id);
                if (line.Is())
                {
                    Model.Item.Line = line;
                }
            }

            return result;
        }

In the example (which is available in this release example, sample.zip file) there is a Chair entity. Catharsis is binding the value types using BindModel(Model.Item) where Item is the new or edited chair instance.

The next step is the 'Separation of concern' pattern. Controller is asking the IColorFacade: Could you give me the Color entity with the ID selected in the combobox? The same for the ILineFacade and the Chair.Line property (referencing the entity Line)

What it in fact means? You are concerning on editing the Chair. Nothing else. There must be already persisted Line and Color, which were selected from the combobox. If not, user has to append new Color or Line in their Infrastructure. Cool! User is the boss. He/She (based on access rights) can extend or remove the list of available Colors and Lines in separate management screens.

Then, when new Chair is added to the system, it uses references to existing entities. That is crucial. Because there is only ONE way how to CRUD the Color - IColorFacade! (And IColorController, IColorDao etc.). You as developr, then can append any business checks there! Ones! and they will be applied for every referencing entity - like Chair in our case.

These Facades (IColorFacade and ILineFacade) are also only responsible for the deleting the Color and Line, and also for assuring that this can be done. If there is any Chair in the system referencing the Color1, the IColorFacade should disable the DELETION of the Color1 entity. And again: only on one place!

Man, that is separation of concern, which will in the future reduce your costs of maintaining and extending.

 

Few notes to the Independent layers:

You can use the IoC containers, as you already mentioned. These will be hook up on your Controller factory. This means:

If someone is asking for ChairController, the IoC container will find out all the 'Dependent' setters like:

public virtual IChairFacade Facade { set; }

public virtual IColorFacade ColorFacade { set; }

public virtual ILineFacade LineFacade { set; }

public virtual IChairModel ChairModel { set; }

And the same for these instances (IColorFacade will be filled with its public virtual IColorDao Dao { set; } etc.)

This approach is sexy at these days, and is called Dependency Injection. If this is done the way just described above, than it is called the Inversion of Control, because the upper layer (the controller factory) is filling the Daos in the Facades (The control is inverted - no more the ColorFacades decides about the ColorDao)

If your infrastructural objects (Facades, Daos, Models) could be singletons, than this approach is simply very good. And sexy last years.

 

But the down side comes, when your Tree structure is to large, and your infrastructural objects are not singletons. Then even if the ChairController executes the action List - all dependent objects are injected and created. And it takes a performance. Because there are sessions for NHibernate etc. Sooner or later you can have ChairController which - to be instantiated - needs to instantiate every Facade and Dao in the system.

This is simple, and the real performance issue, which you will face sooner or later.

 

We for Catharsis decided to go the way through the Service locator - lazy initialization.

If you could need - only for few actions of your ChairController the ILineFacade, then use:

public virtual ILineFacade LineFacade
        {
            protected get
            {
                if (_lineFacade.IsNull())
                {
                    _lineFacade = FacadeFactory.CreateFacade<ILineFacade>(Model.Messages);
                }
                return _lineFacade;
            }
            set
            {
                Check.Require(value.Is(), " ILineFacade cannot be null");
                _lineFacade = value;
            }
        }

As you can see - the setter is still public (The IoC container still will WORK!!!) But if not set externally, then the LineFace is instantiated only when needed.

This approach is at last years called obsolete. But we proved, that it is only fairy-tale, the marketing trick, how to involve the people to be relaying on external IoC containers.

 

Anyhow, Anatoliy, please, if you want, create working example (which could be published). I will gladly expose it here! Becasue that's the purpose of the Catharsis being an opensource.

Thanks for all your suggestions, and ideas, they really look good!!!

And do look forward the Catharsis next release, which will be really more sexy :) (Wiki parser, no strings, Validators... :)

Enjoy good projects

Radim Köhler