While we recommend using "new" to create the entity within a factory method, the CreateEntity factory is available and merits some consideration. This topic describes it, when you might want to use it, and why you probably don't.
We generally recommend that you call a constructor within a factory method when creating a new entity ... as we typically do throughout this documentation. Here's a simple factory method that uses "new".
C# | public Customer CreateCustomer() { return new Customer(); // more to follow } |
VB | Public Function CreateCustomer() As Customer Return New Customer() ' more to follow End Function |
DevForce offers an alternative approach that uses the CreateEntity factory method of the EntityManager. Here's the same example - or close to it - written with CreateEntity:
C# | public Customer CreateCustomer(EntityManager manager) { return manager.CreateEntity<Customer>(); // more to follow } |
VB | Public Function CreateCustomer(ByVal manager As EntityManager) As Customer Return manager.CreateEntity(Of Customer)() ' more to follow End Function |
Although this approach requires the help of an EntityManager, it doesn't actually add the new Customer to the manager. You have to do that in a separate step. It differs substantively from "new" in these respects:
Many of us fail to see the advantage of these differences.
The CreateEntity method embeds an EntityManager within the new entity. It's presence enables the following technique for adding the entity to the EntityManager:
C# | cust.EntityAspect.AddToManager(); |
VB | cust.EntityAspect.AddToManager() |
You can't call AddToManager on an entity you created with "new". You have to write:
C# | manager.AddEntity(cust); |
VB | manager.AddEntity(cust) |
The embedded EntityManager is otherwise inaccessible as demonstrated in these tests:
C# | var cust == manager.CreateEntity<Customer>(); // hides an EntityManager inside the entity Assert.IsNull(cust.EntityAspect.EntityManager); // EntityManager is not visible cust.EntityAspect.AddToManager(); // adds the entity to the hidden EntityManager Assert.IsNotNull( cust.EntityAspect.EntityManager()); // now you see it. |
VB | Dim cust = manager.CreateEntity(Of Customer)() ' hides an EntityManager inside the entity Assert.IsNull(cust.EntityAspect.EntityManager) ' EntityManager is not visible cust.EntityAspect.AddToManager() ' adds the entity to the hidden EntityManager Assert.IsNotNull(cust.EntityAspect.EntityManager()) ' now you see it. |
The non-generic overload of CreateEntity has potential in a few scenarios. It could be convenient if you were writing a general utility that created entities as one of its duties.
C# | public object CreateUserSelectedEntity(EntityManager manager, Type entityType) { var anEntity = manager.CreateEntity(entityType); // do something with it return anEntity; } |
VB | Public Function CreateUserSelectedEntity(ByVal manager As _ EntityManager, ByVal entityType As Type) As Object Dim anEntity = manager.CreateEntity(entityType) ' do something with it Return anEntity End Function |
It is modestly difficult to "new" a class when you don't know its type. The DevForce CreateEntity method does it without ceremony.
Stick with "new" unless you are writing an entity creation utility.