-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: CSLA Databinding NUndo features
PostPosted: Tue Oct 02, 2007 11:56 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Hello Forum,
I would like me ask you about CSLA subset features, concretely, DataBinding and N-Undoable objects. However I can't understand how do translate a Entity class to Entity BussinessObject.

For example in my MVC prohects, I have in Model a class as:

public class Customer {

private int customer_id;
private string name;
private IList<Invoice> invoices;

public Customer () {

}

}

And NHibernate works with these objects. However, if I design a form in order to edit a Customer, I will contain TextBox for Name property and a DataGrid for invoices list. So, in View I would have something as?:

public class CustomerBO : Csla.BussinessBase<Customer> {
??????
??????
}

What about invoices Ilist? How Can I clsa-ing?

How implement IList as BO? How Can I translate a Entity object to Business Object and viceversa?

Thanks you in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 02, 2007 3:24 pm 
Beginner
Beginner

Joined: Sat Jul 21, 2007 3:56 pm
Posts: 27
Hello jeusdi,

I am also using Csla (at least a subset of it) to do the binding between my business entities and my user controls. My business entities are all subclasses of one of Csla's base classes, this way they all implement the necessary interfaces for data binding. on top of that, I have adapted Csla's base collection a bit so I can use it as a wrapper around the IList child collections that NHibernate gives me.

Out of the box this solution was not yet perfect for me, especially when you want to do inline editing in a grid to add, modify or remove entities from the collection. Therefore I have created my own base collection on top of Csla's one.

If you are interested in the code, you can find it here: http://www.paarden.be/NHibernate/Sol_PaardenConfigurator.zip

About the multi-level undo capabilities of Csla, I don' t think it is possible to use it in combination with NHibernate. In fact, in my opinion, while the concept of it seems really interesting, the way it is implemented makes it a bit useless in most scenarios: the BeginEdit clones the whole object graph and puts it on a stack and the CancelEdit discards the object graph currently in use and replaces it with the cloned one from the stack. This means that any code that has a reference to the discarded object graph will fail to work.

I hope this helps,

Tolomaüs.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 03, 2007 2:39 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Tolomaüs wrote:
My business entities are all subclasses of one of Csla's base classes, this way they all implement the necessary interfaces for data binding.


How do you do it? Can you write a very very simple example with an Entity example?

Reflection, I've read about CSLA. I think combines CSLA with Nhibernate isn't correct:

--> CSLA implements all methods, rules, ... in only one Business Object. It's incompatible with NHibernate or isn't used all features of NHibernate and CSLA.
--> I think that in MVC pattern CSLA is not applicable.
--> What about lists?

And I think that is we are using only Binding CSLA features, Why not use IEditableObject, IBindingList, ... How I can use them with out Nhibernate Entities?

I will see your framework.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 03, 2007 4:28 pm 
Beginner
Beginner

Joined: Sat Jul 21, 2007 3:56 pm
Posts: 27
Hmm, interesting question. I haven't thought yet about if and how the MVC pattern is applied in this Csla/NHibernate solution, but I guess the controller functionalities are spread out over:

1) the use case controller, that retrieves the necessary object graph from the business layer (i.e. the Model) and hands it over to the user control (i.e. the View)

2) the Csla collection wrapper that provides the two-way synchronization between the business objects and the user control

3) the IEditableObject, ... implementations that are part of the business objects' base class. They too handle some of the communication between a business object and the user control.

This last point shows that one part of the controller is actually part of the model. I don't know if this is "bad design", but it is the result of how .NET's object model itself is designed.

I think the correct name for this pattern is in fact MVP (model-view-presenter) and not MVC. The presenter only presents the model to the view (point 1)) and from then on the model and view handle all the binding with each other themselves.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 04, 2007 7:38 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Tolomaüs wrote:
My business entities are all subclasses of one of Csla's base classes, this way they all implement the necessary interfaces for data binding.


How do you do it? Can you write a very very simple example with an Entity example?

Reflection, I've read about CSLA. I think combines CSLA with Nhibernate isn't correct:

--> CSLA implements all methods, rules, ... in only one Business Object. It's incompatible with NHibernate or isn't used all features of NHibernate and CSLA.
--> I think that in MVC pattern CSLA is not applicable.
--> What about lists?

And I think that is we are using only Binding CSLA features, Why not use IEditableObject, IBindingList, ... How I can use them with out Nhibernate Entities?

For example, we could implement our BusinessObject as -->

Code:
    public abstract class BusinessObject<T> : System.ComponentModel.IEditableObject, System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.IDataErrorInfo
    {

        entity T;

        public BusinessObject(T entity)
        {
            this.entity = entity;
        }

        public T getEntity () {
             return this.entity;
        }

        #region IEditableObject Members

        public void BeginEdit()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void CancelEdit()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void EndEdit()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region INotifyPropertyChanged Members

        event System.ComponentModel.PropertyChangedEventHandler System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        {
            add { throw new Exception("The method or operation is not implemented."); }
            remove { throw new Exception("The method or operation is not implemented."); }
        }

        #endregion

        #region IDataErrorInfo Members

        public string Error
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        public string this[string columnName]
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        #endregion
    }


and so, if I want a BusinessObject, only is necessary inherit from BusinessObject Class:

public class EntityBO : BusinessObject<Model.Entity>

However, What about an User Entity has a invoices List. It would be very interesting, convert automatically this List in order to implement IBindingList<T> (T is businessObject) automatically (I'm thinking about a Dinamic Proxy). Or use a factory method that creates a BusinessObject from an Entity. For example,

public BusinessObject<T> createBOFromEntity (T ent) {
return ...
}

Sumarising, would be very very interesting transform a simple Entity to a EntityBO that implements IEditableObject, INotifyPropertyChanged, IDataErrorInfo. And if this Entity had collections, these ones would have to implement IBindingList. This situation would be the best for us. In order to implement this, I thought use DynamicProxies (Castle Porject, ...). So Entity has all NHibernate features and we would add all Binding features and others...
What about this idea?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 04, 2007 3:08 pm 
Beginner
Beginner

Joined: Sat Jul 21, 2007 3:56 pm
Posts: 27
Hello jeusdi,
Quote:
and so, if I want a BusinessObject, only is necessary inherit from BusinessObject Class:

public class EntityBO : BusinessObject<Model.Entity>


Indeed, that's exactly how I did it myself:

Code:
    public class Entity : BusinessBase<Entity>
    {
     .....
     }


where Entity stands for all my business objects and BusinessBase is the Csla base class that implements all the necessary binding interfaces. So you don't have to transform the NHibernate-aware classes to binding-enabled classes, you yjust have your NHibernate-aware classes subclass from the BusinessBase.

Quote:
However, What about an User Entity has a invoices List.


Csla also provides a collection class - the BusinessListBase - that implements all the necessary binding interfaces. But I found out that it would take a lot of complex coding to be able to use this collection class in NHibernate directly. With "directly" I mean that you would just mention it in the mapping of your parent object and you would retrieve a child collection of type BusinessListBase.

Instead, I stayed with the simpler IList to retrieve my collection from NHibernate. And whenever I need this collection to support the binding interfaces, I wrap Csla's BusinessListBase around it. So when I want to show a collection of entities in a grid, I write this code:

Code:
EntityList<Organisation> bindableOrganisationList = new EntityList<Organisation>(organisationList);
organisationBindingSource.DataSource = bindableOrganisationList;


where organisationList is the IList I received from the NHibernate session and EntityList is my own collection subclassed from Csla's BusinessListBase:

Code:
    public class EntityList<C>: BusinessListBase<EntityList<C>,C> where C : EntityBase
    {
     ...
     }


I hope I have made myself a bit clear. If not, let me know!

Tolomaüs.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 09, 2007 4:33 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
What about this approach?

I've created a BussinesObject Factory -->

Code:
    public class FactoryBO
    {

        private static Type[] get_interfaces()
        {
            Type[] interfaces = new Type[3];

            interfaces[0] = typeof(System.ComponentModel.IEditableObject);
            interfaces[1] = typeof(System.ComponentModel.INotifyPropertyChanged);
            interfaces[2] = typeof(System.ComponentModel.IDataErrorInfo);

            return interfaces;
        }

        public static UserBO createUserBO()
        {
            return (UserBO)new Castle.DynamicProxy.ProxyGenerator().CreateClassProxy(typeof(UserBO), FactoryBO.get_interfaces(), new BusinessObjectInterceptor<Model.Entities.User>());
        }

        public static UserBO createUserBO(Model.Entities.User user)
        {
            return (UserBO)new Castle.DynamicProxy.ProxyGenerator().CreateClassProxy(typeof(UserBO), FactoryBO.get_interfaces(), new BusinessObjectInterceptor<Model.Entities.User>(), new object[] { user.Name, user.Second_name });
        }
    }


As you can see, the finallity is create a Bussines Object with IEditableObject, INotifyPropertyChanged, IDataErrorInfo implementation.

So, If you has your Model Entities, for example User, you could do something as:

Code:
    public class UserBO : Model.Entities.User
    {
        public UserBO() : base()
        {

        }

        public UserBO(string name, string second_name) : base(name, second_name)
        {

        }
    }


A Bussines Object that inherits from our Model Entities!!!
So, mmm

Code:
    public class UsersFormFactory : WinView.Classes.FormsFactory<WinView.Forms.UsersForm, Model.Entities.User>
    {
        public UsersFormFactory()
        {

        }

        public override WinView.Forms.UsersForm getEmptyForm()
        {
            return new WinView.Forms.UsersForm(WinView.BusinessObjetcs.FactoryBO.createUserBO());
        }

        public override WinView.Forms.UsersForm getFilledForm(Model.Entities.User user)
        {
            return new WinView.Forms.UsersForm(WinView.BusinessObjetcs.FactoryBO.createUserBO(user));
        }
    }


As you can see I've implemented a FormFactory in order to create a UserForm with user data (from Model (NHibernate)). This function creates a UserBO (that implments IEditableObject, INot... interfaces). When Form contructor is performed -->

Code:
        public UsersForm(WinView.BusinessObjetcs.UserBO user) : this()
        {
            this.user = new Model.Entities.User("nom", "cognom");
            this.userBindingSource.DataSource = this.user;
        }


All works very well, however there is something that:

Castle.DynamicProxy.ProxyGenerator().CreateClassProxy(typeof(UserBO), creates a new instance of UserBO, so the object returned isn't the original object that we've get from NHibernate!!! So, I'm creating a copy of my entity with binding capabilities. The total solution would be can wrapper NHibernate Entity on Binding features. I need to solve it, yet.

This is a first approach in order to obtain a possible framework. I believe that have to be able to make a framework that creates bindable features on existing objects.

What do you thing about all?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 09, 2007 7:11 am 
Beginner
Beginner

Joined: Sat Jul 21, 2007 3:56 pm
Posts: 27
So you mean that you want to subclass your business entity at runtime with a class that implements all the binding interfaces? I have no idea if this is possible at all as I don't know anything of the Castle components.

But in case you have no access to the code of your business entity classes this could be an interesting approach. But indeed, you will have to adapt/extend the object creation process of NHibernate internally, so it gives you directly the run-time created subclass.

Another possibility could be to use ObjectViews. It puts the binding stuff in a separate row-class that is wrapped around each business object you want to view.

But whenever you do have access to the code of your business object, as in 99% of the cases, I still prefer to just subclass my business objects from the Csla base class. This seems to me the most easy, maintainable and performant way of solving the problem.

Don't you think?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 09, 2007 7:28 am 
Beginner
Beginner

Joined: Tue May 02, 2006 8:04 am
Posts: 34
Quote:
So you mean that you want to subclass your business entity at runtime with a class that implements all the binding interfaces? I have no idea if this is possible at all as I don't know anything of the Castle components.


It is possible with the Spring.NET framework, I've done it. It's even demonstrated in their quickstarts.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.