Hello!
Whilst refactoring an application, I was looking at optimizing a
ModelFactory with generics. Unfortunately, the business objects created by
the ModelFactory doesn't provide public constructors (because we do not
allow developers to instantiate them directly).
Because our business objects are instantiated very frequently, the idea of
using reflection sounds like a performance killer (I haven't done any tests
on this, but the documentation suggests that Activator.CreateInstance() is
slower than newing up objects directly).
The goal is to have a central access point for creating models (hence the
use of a factory), so that all objects are guaranteed a common state before
being handed over to other tiers.
The following sample illustrates the desired behaviour:
public abstract class CmsObjectNode
{
internal CmsObjectNode(CmsContext c) {}
}
public sealed class Page : CmsObjectNode
{
internal Page(CmsContext c) : base(c) { }
}
// User
// Role
// etc.
static class ModelFactory
{
//
public static Page CreatePage(CmsContext c)
{
return new Page(c);
}
// CreateUser
// CreateRole
// etc.
public static T CreateCmsObjectNode<T>(CmsContext c) where T :
CmsObjectNode
{
return new T(c);
}
}
...
I then thought: "Perhaps I could put the factory method on each business
type instead (just for testing purposes), and have the factory use that ..".
The following sample illustrates the factory method implementation:
public abstract class CmsObjectNode
{
internal CmsObjectNode(CmsContext c) {}
internal abstract T Create<T>(CmsContext c) where T : CmsObjectNode;
}
public sealed class Page : CmsObjectNode
{
internal Page(CmsContext c) : base(c) { }
override internal Page Create<Page>(CmsContext c)
{
return new T(c);
}
}
// User
// Role
// etc.
static class ModelFactory
{
//
public static Page CreatePage(CmsContext c)
{
return new Page(c);
}
// CreateUser
// CreateRole
// etc.
public static T CreateCmsObjectNode<T>(CmsContext c) where T :
CmsObjectNode
{
return new T(c);
}
}
I see two solutions to this problem:
1. Keep the current ModelFactory with concrete methods (although I don't
like the redundance pattern).
2. Replace requests to the ModelFactory with request to each type instead.
This provides a single access point for creating types - and the factory
method would reside on the concrete implementation.
I feel that models and factories should be seperated, but I can't see a
solution to the above.
Thanks in advance!
--
With regards
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)