CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Forum has moved

New location: CSLA .NET forum


CSLA .NET Resources:
  • CSLA .NET forum
  • CSLA .NET home page
  • ObjectFactory with different types of BOs

    rated by 0 users
    Answered (Verified) This post has 1 verified answer | 6 Replies | 1 Follower

    Not Ranked
    6 Posts
    mspaourh posted on Tue, Dec 27 2011 7:57 AM

    Hi everyone,

    Is it possible to use a single ObjectFactory class that determines the type of BO to operate on at run-time?

    There is a custom base class (e.g subclass of ReadOnlyBase<T>) that has the ObjectFactoryAttribute applied on it and all its subclasses should use the same ObjectFactory, unless otherwise specified.

    There seems to be no way of communicating the actual business object type from the FactoryDataPortal to the ObjectFactory instance.

    Using CSLA 3.8.4

     

    Thanks in advance,

    Mario

    Answered (Verified) Verified Answer

    Top 10 Contributor
    2,279 Posts
    Verified by mspaourh

    Hmmmm,

    You could create your own ObjectFactoryLoader  - responsible for creating an instance of the ObjectFactory.

    Basically the name is just a string (and using the default ObjectFactoryLoader this should be a fully qualified class name) and optionally  specify other names for the Create/Update/Delete/Fetch methods.

    And if you create your own ObjectFactoryLoader you can decide yourself what the name value should contain. Meaning that you could specify the ObjectFactory attribute with a fully qualified name and actual type - andimplement your own convention to initialize the factory class with actual type name,  tho' that would require an ObjectFactoryAttribute on each class.

    You should be able to use a generic constraint on the ObjectFactory class - but this would also require the ObjectFactory attribute on each class. It would however allow you to have an object factory that could create multiple types.

      [ObjectFactory(typeof(MyRootFactory<Root>))]
      public class Root : BusinessBase<Root>

    and
      public class MyRootFactory<T> : Csla.Server.ObjectFactory
      {
     
        public T Create()
        {
          T o = (T)MethodCaller.CreateInstance(typeof(T));
     
          return o;
        }
    }
    this will work with the default ObjectFactoryLoader.

    Besides that - I do not know of any other method or provision for sending the actual object type to the ObjectFactory! Hmm

     

    Jonny Bekkum, Norway CslaContrib Coordinator

    All Replies

    Top 10 Contributor
    2,279 Posts
    Verified by mspaourh

    Hmmmm,

    You could create your own ObjectFactoryLoader  - responsible for creating an instance of the ObjectFactory.

    Basically the name is just a string (and using the default ObjectFactoryLoader this should be a fully qualified class name) and optionally  specify other names for the Create/Update/Delete/Fetch methods.

    And if you create your own ObjectFactoryLoader you can decide yourself what the name value should contain. Meaning that you could specify the ObjectFactory attribute with a fully qualified name and actual type - andimplement your own convention to initialize the factory class with actual type name,  tho' that would require an ObjectFactoryAttribute on each class.

    You should be able to use a generic constraint on the ObjectFactory class - but this would also require the ObjectFactory attribute on each class. It would however allow you to have an object factory that could create multiple types.

      [ObjectFactory(typeof(MyRootFactory<Root>))]
      public class Root : BusinessBase<Root>

    and
      public class MyRootFactory<T> : Csla.Server.ObjectFactory
      {
     
        public T Create()
        {
          T o = (T)MethodCaller.CreateInstance(typeof(T));
     
          return o;
        }
    }
    this will work with the default ObjectFactoryLoader.

    Besides that - I do not know of any other method or provision for sending the actual object type to the ObjectFactory! Hmm

     

    Jonny Bekkum, Norway CslaContrib Coordinator

    Not Ranked
    6 Posts

    JonnyBee,

    thanks for your answer.

    I am trying to drop the requirement of applying the ObjectFactoryAttribute to each subclass.

    The intention is to provide a "default" behavior for all subclasses of the custom base class by applying the attribute to the custom

    base class. The behavior can be replaced by explicitly applying the attribute to some subclass.

    I am aware of the ObjectFactoryLoader class and the IObjectFactoryLoader interface and was intending

    to use them in this concept. The custom ObjectFactoryLoader could use

    public virtual Type MakeGenericType(
        Type[] typeArguments
    )

    on the System.Type instance "described" (by interpreting the string) in the ObjectFactoryAttribute to make a closed constructed type,
    but the actual BO type (Root in your example) required for typeArguments is missing from the whole "context".

    Top 10 Contributor
    2,279 Posts

    Hi,

    Yes, you are correct and IMO it is not intended to work the way you want to use it.

    An ObjectFactory must have knowledge of how to create/fetch/update/delete the data and maintain state in the BO. And for an object structure with miltiple levels it must also have knowledge of all the child object factories.

    The ObjectFactoryAttribute is only intended to be used on "root" objects - ie CSLA DataPortal will only use the ObjectFacotryAttribute for the "root" object. .

     

    Jonny Bekkum, Norway CslaContrib Coordinator

    Not Ranked
    6 Posts

    Hi,

    The use of factories in general is required due to plugging of different DALs. An ObjectFactoryLoader takes care of that.

     

    Let me explain what is the goal here. There dozens of database tables (and hence BOs) that have identical structure, e.g.

    ID INT NOT NULL PRIMARY KEY,

    CODE NVARCHAR(5),

    DESCR NVARCHAR(50)

    When their data is loaded in an list (editable or read-write) its done with an SQL statement like

    SELECT ID, CODE, DESCR FROM <<tableName>>

    and when they are loaded as root objects its done with

    SELECT ID, CODE, DESCR FROM <<tableName>> WHERE ID=@ID
    . Same pattern with the insert, update, delete statements.

    tableName can be derived from the business object type name (using the appropriate convention, or a user-defined attribute in the worst case).

    All of the relevant business object classes are derived from the appropriate custom base class.

    The "generic" factory is a reasonable choice because is a time and effort saver.

    Currently the only limitation for this implementation is the requirement to place an ObjectFactory (or a custom subclass of it!) to every business object class!

    Top 10 Contributor
    2,279 Posts

    For now - my recommendation would be to create a ObjectFactory derived base class (ex NameValueListFactory)  to implement the "generic" object factory and create a new (nearly empty) ObjectFactory class to keep 1:1 mapping between object type and table.

    The actual ObjectFactory would inherit from the NameValueListFactory and just set the table name to use.

     

     

    Jonny Bekkum, Norway CslaContrib Coordinator

    Not Ranked
    6 Posts

    Thanks jonny.

     

    Although its not what I actually planned, i'll just stick with that.

     

    Happy 2012 to everyone!

     

    Mario

    Page 1 of 1 (7 items) | RSS

    Copyright (c) 2006-2014 Marimer LLC. All rights reserved.
    Email admin@lhotka.net for support.
    Powered by Community Server (Non-Commercial Edition), by Telligent Systems