Implementing a Factory Pattern with CSLA.NET - c#

I would like to implement Factory Pattern in CSLA. I can use an abstract base class or an interface for the abstraction. I have decided to use an abstract class, only because I have certain common functionality such as, saving to store, retrieving from store, and deletion of the record. Also, some properties that would apply to all implemented objects.
C# only allows for inheritance from one class, so I can either use BusinessBase or the abstract class. I would also like the concrete types to have their own set of business rules. How can this be done with CSLA?
If I do what I have listed below, will the rules in both the abstract class as well as the concrete class get fired?
Some code ...
Abstract class:
public class Form : BusinessBase<Form> {
private static PropertyInfo<string> FormNameProperty = RegisterProperty<string>(c => c.FormName);
public string FormName
{
get { return GetProperty(FormNameProperty); }
}
public abstract void LoadContent();
protected override void AddBusinessRules()
{
// business rules that are commmon for all implementations
}
}
Concrete implementation:
public class FormA : Form {
private static PropertyInfo<string> FirstNameProperty = RegisterProperty<string>(c => c.FirstName);
public string FirstName
{
get { return GetProperty(FirstNameProperty); }
}
public override void LoadContent(){
// some custom code
}
protected override void AddBusinessRules()
{
// business rules that only apply to this class
}
}
Factory:
public static class FormFactory{
public static Form GetForm(string formanmae) {
Type formType = GetFormType(formName);
if(formType == null)
return null;
var form = Activator.CreateInstance(formType) as ReferralForm;
return form;
}
}

Instead of using Activator.CreateInstance, you should use the Csla DataPortal.
var form = (Form)Csla.DataPortal.Create(formType, new Csla.Server.EmptyCriteria);
This way you are creating your business object using the Csla way, so any rules that should be run will be.

Related

Can I choose which constructor Unity will use?

Is it possible to specify in a Unity Resolve which constructor Unity should use?
The object I am trying to create may look something like this:
public class MyObject
{
[UseWhenSunny]
public MyObject(InputOne one)
{
Console.WriteLine("Chose constructor one");
}
[UseWhenRaining]
public MyObject(InputTwo two)
{
Console.WriteLine("Chose constructor two");
}
}
public class InputOne
{
}
public class InputTwo
{
}
My construction could be something like this:
var container = new UnityContainer();
container.RegisterInstance(new InputTwo());
var myObject = container.Resolve<MyObject>();
I can find the correct ConstructorInfo easily enough, but I have not figured out how to force Unity to use this specific constructor?
It's a strange construct when you use different constructors for states within a game/program. If you want to pass two different class types, you could use inheritance for that. You need a common ancestor because InputOne and InputTwo only shares Object as common ancestor. So you need to specify a new base class. In this base class you write the common functionality/definition.
Here is an example:
public abstract class InputBase
{
public abstract void Show();
}
public class InputOne : InputBase
{
public override void Show()
{
Console.WriteLine("Show one");
}
}
public class InputTwo : InputBase
{
public override void Show()
{
Console.WriteLine("Show two");
}
}
public class MyObject
{
public MyObject(InputBase input)
{
// because InputOne and InputTwo can be casted to their base class
// they both can be passed as InputBase.
// InputBase defines the Show method which their derived ones must
// implement (abstract).
input.Show();
}
}
See Inheritance (C# Programming Guide)

Mapping classes c#

I am writing a tranformer that takes some input and gives an output.I need to call a specific tranformer based on my input type.
public static myentrypoint( template t);
{
//I could do something like this.
switch(t)
{
case t1:
transformt1(..);
case t2:
transformt1(..);
....
}
}
Trasform1 : Itransform
{
tranform1(...);
}
Trasform2 : Itransform
{
tranform2(...);
}
I need to map which function to call based on what my template is. I can do a switch but are there more cleaner ways to do this using some design patterns ? I was thinking a of writing a static dictionary. I am new to OOP so any suggestions would be great.
If template is a class, and each template potentially has a different transform, then why not just include the transform function inside of your template class?
public static myentrypoint( ITemplate t);
{
t.transform();
}
The way that I do these types of situations is through the use of Generics. (Shameless self-promotion of a blog post)
Basically, you'll have your base class set up like this:
public abstract class Transformer<T>
where T : Template
{
public abstract void Transform(T item);
}
Then you derive for each of your types like this:
public class Transformer1 : Tansformer<Template1>
{
public void Transform(Template1 item)
{
}
}
public class Transformer2 : Transformer<Template2>
{
public void Transform(Template2 item)
{
}
}
Then you'll just need a factory to give you the correct Transformer.
public class TransformFactory
{
public Transformer<T> GetTransformer<T>(T item)
{
if (item is Template1)
return new Transformer1();
else if (item is Template2)
return new Transformer2();
// ...
}
}
The benefit of this approach is that you'll be able to encapsulate all behavior on that specific type in the concrete implementations. If there is any common behavior on them all, you can do that in the abstract base.
Invoking methods based on a parameter without switch-case statements in C#
In OOP, based on the [open/close principle] which says that software entities such as classes and functions should be open for extension, but closed
for modification.
Methods which use switch-case statement would call this principle into question. In order to implement this principle inside the codes without
causing changes in their functionality.
We use a pattern named "Delegate Dictionary Pattern".
For example, we have an entity named Template that keep input values as well as some of Transform classes for processing this Template.
Template class for keeping input value
public class Template
{
public int TransformNo { get; set; }
public string Title { get; set; }
}
ITransform interface for transform abstract
public interface ITransform
{
void Do(Template template);
}
Transform1 as a concrete class of ITransform
public class Transform1 : ITransform
{
public void Do(Template template)
{
Console.WriteLine($"Transform : {template.TransformNo}, TemplateTitle : { template.Title}");
}
}
Transform2 as a concrete class of ITransform
public class Transform2 : ITransform
{
public void Do(Template template)
{
Console.WriteLine($"Transform : {template.TransformNo}, TemplateTitle : { template.Title}");
}
}
TransformCordinator class for coordinating template of *ITransformer**
public class TransformCordinator
{
Dictionary<int, Action<Template>> transformMap = new Dictionary<int, Action<Template>>();
public TransformCordinator()
{
transformMap.Add(1, x => new Transform1().Do(x));
transformMap.Add(2, x => new Transform2().Do(x));
}
public void Do(Template template)
{
transformMap[template.TransformNo](template);
}
}
// example
class Program
{
static void Main(string[] args)
{
var transformCordinator = new TransformCordinator();
transformCordinator.Do(new Template() { TransformNo = 1, Title = "Hi!" });
Console.ReadLine();
}
}

Is There a Name for this Pattern

I've used this pattern many times in a variety of places, usually alongside a plugin pattern.
Some example ways I've used it are for messaging systems, such as creating subscribers to various types of unrelated messages. I've also used it for generic integration workflows that each need a differently shaped context object.
Basically the pattern consists of defining a blank marker interface for a message or context. Then defining a high level workflow interface that works with the message/context interface. You can then use a factory to get a concrete instance of the workflow, and if needed, the workflow can also be responsible for parsing its message / context from a common data format.
Next, you create an abstract generic base workflow whose responsibilty is just to map calls to the interface methods, which pass around the useless marker interface, into calls to abstract methods that take the concrete version of the message/context.
Hopefully that makes sense. I'll provide a code example below. I'd love to know if this pattern has a name because I've noticed that I've used it about 4-5 times now. Also, I'm just fleshing out how to explain the pattern, so if anything about my explanation doesn't make sense please let me know that as well.
The main point is that you can have multiple classes with different method signatures that can still be called via a common interface:
End Result
public class ConcreteA : Base<MessageA>
{
public void Process(MessageA message){...}
public MessageA Parse(IDictionary data){...}
}
public class ConcreteB : Base<MessageB>
{
public void Process(MessageB message){...}
public MessageB Parse(IDictionary data){...}
}
//And both can by called by...
public void Main(){
var data = GetDataFromIntegrationSource(someContext);
IWorkflow impl = Factory.GetConcrete(someContext);
//So in your classes you're able to work with strongly typed parameters,
//But in the consuming code you still can use a common interface
//Consuming code never even knows what the strong type is.
IMessage msg = impl.Parse(data);
impl.Process(msg);
}
FULL EXAMPLE
High Level Interfaces
public interface IGenericeMarkerInterface
{
}
public interface IGenericWorkflow
{
void Process(IGenericeMarkerInterface messageOrContext);
IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat);
}
Abstract Base for Mapping to Concrete Methods
public abstract class GenericWorkflowBase<T> : IGenericWorkflow where T : IGenericeMarkerInterface
{
public void Process(IGenericeMarkerInterface messageOrContext)
{
Process((T)messageOrContext);
}
public IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat)
{
return DoParse(commonDataFormat);
}
public abstract void Process(T messageOrContext);
public abstract T DoParse(IDictionary<string, string> commonDataFormat);
}
Mapping Attributes
public class MappingAttributeUsedByFactoryAttribute : Attribute
{
public WorkflowType SomePropertyForMapping { get; set; }
}
Concrete Implementations
public class SomeRandomlyShapedMessageOrContext : IGenericeMarkerInterface
{
public int ID { get; set; }
public string Data { get; set; }
}
[MappingAttributeUsedByFactory(WorkflowType.IntegrationPartnerB)]
public class ConcreteWorkflow : GenericWorkflowBase<SomeRandomlyShapedMessageOrContext>
{
public override void Process(SomeRandomlyShapedMessageOrContext messageOrContext)
{
//TODO: process the strongly typed message
}
public override SomeRandomlyShapedMessageOrContext DoParse(IDictionary<string, string> commonDataFormat)
{
//TODO: parse the common data into the strongly typed message
}
}
Factory
public static class WorkflowFactory
{
public static IGenericWorkflow Get(WorkflowType workflow)
{
//TODO: find the concrete workflow by inspecting attributes
}
}
Example Usage
public static class Program
{
public static void Main(string[] args)
{
//this could be driven by a UI or some contextual data
var someSortOfWorkflowIdentifier = (WorkflowType)args[0];
var data = GetSomeDictionaryOfData();
var workflow = WorkflowFactory.Get(someSortOfWorkflowIdentifier);
workflow.Process(workflow.Parse(data));
}
}
Yes, it's exactly same as you named it: Marker interface

C# Class following an interface and contains methods from abstract

I try to achieve the following: I have an interace called IAxis that forces my class TheAxis to have certain methods. In addition I want to implement some kind of abstract class based on a parameter. To explain this will write it down in code:
class TheAxis : IAxis
{
public TheAxis(){ }
public void IMoveToPos(int pos) {} //This is forced by the Interface
}
As the instance of this class is called it should be able to choose which methods to include, similar to virtual methods but not overriding existing methods but adding already coded ones from another class. I am looking for something like this:
abstract class GateAxis
{
public void CloseGate() { IMoveToPos(0); }
}
abstract class XAxis
{
public void MoveToStart() { IMoveToPos(100); }
}
TheGateAxis = new Axis() as GateAxis;
Now I want to be able to use TheGateAxis.Closegate(); but NOT TheGateAxis.MoveToStart();
if I call
TheXAxis = new Axis() as XAxis;
I want to be able to use TheXAxis.MoveToStart(); but NOT TheXAxis.CloseGate();
The Methods Given in XAxis or GateAxis donĀ“t need any methods from TheAxis except the onces given by the interface.
Is it possible to do somethign like that? To add Methods to a class depending on a parameter given while instancing the class?
I hope you get what I am trying to do as I do hard to explain.
Best,
Kevin
Well, if you want classes sharing few methods from a base class, and other being separate, you could do
//an interface (optional)
public interface IAxis {
void MoveToPos(int pos);
}
public abstract class AxisBase : IAxis {
public void MoveToPos(int pos) {
//implementation
}
}
//optionally you can do an IGateAxis interface, inheriting (or not) from IAxis
public interface IGateAxis : IAxis {
void CloseGate();
}
//classes inheriting from AxisBase, implementing IGateAxis
public class GateAxis : AxisBase, IGateAxis {
public void CloseGate() {
MoveToPos(0);
}
}
//another interface, not inheriting from IAxis
public interface IXAxis {
void MoveToStart();
}
//another class inheriting from AxisBase
public class XAxis : AxisBase, IXAxis {
public void MoveToStart() {
MoveToPos(100);
}
}
usage
var gateAxis = new GateAxis();
gateAxis.CloseGate();
//and you can do
gateAxis.MoveToPos(250);
var xAxis = new XAxis();
xAxis.MoveToStart();
//and you can do
xAxis.MoveToPos(40);
with the IGateAxis interface
IGateAxis gateAxis = new GateAxis();
gateAxis.CloseGate();
gateAxis.MoveToPos(1);
with the IXAxis interface
IXAxis xAxis = new XAxis();
gateAxis.MoveToStart();
//but you can't do
//gateAxis.MoveToPos(10);
//as IXAxis doesn't know about this method.
// super class
abstract class TheAxis : IAxis {
public TheAxis() { }
public void IMoveToPos(int pos) { } //This is forced by the Interface
}
abstract class GateAxis : TheAxis {
public virtual void CloseGate() { IMoveToPos(0); }
}
abstract class XAxis : TheAxis {
public virtual void MoveToStart() { IMoveToPos(100); }
}
Now if you derive a class from GateAxis it'll only have access to the interface methods and the methods from GateAxis. Same goes for TheAxis.
Dynamically adding methods, and removing them is not something that you can do in "normal" C# . There is no any OOP pattern that can simulate this.
What you can do, is using ExpandoObject to be able to achieve exactly what you're trying to achieve.
Represents an object whose members can be dynamically added and
removed at run time.
By the way I would not encourage of using it as you are in statical type language domain, so may be it's a godd idea to revise your architectiure a little bit and don't jump in dynamic language domain using C#.
I think the best way to solve this is to use interfaces and a single (base) class.
public interface IAxis {
void MoveToPos(int pos);
}
public interface IGateAxis {
void CloseGate();
}
public interface IXAxis {
void MoveToStart();
}
public class TheAxis : IAxis, IGateAxis, IXAxis {
public TheAxis(){ }
void IAxis.MoveToPos(int pos) {}
void IGateAxis.CloseGate() { ((IAxis)this).MoveToPos(0); }
void IXAxis.MoveToStart() { ((IAxis)this).MoveToPos(100); }
}
IGateAxis gateAxis = new ThisAxis();
gateAxis.CloseGate();
IXAxis xAxis = new ThisAxis();
xAxis.MoveToStart();
This way you can specify which methods are available to certain types of axis. Also, you could force the creation of axis through a factory pattern, or even a single static method, just to facilitate the creation of axis.
Assuming you have more than 3 methods, the easiest way that I see is to simply create a proxy that acts as a chain of responsibility:
public class AxisProxy : IAxis
{
public AxisProxy(params IAxis[] implementations) {
this.implementations = implementations;
}
private IAxis[] implementations;
public virtual void CloseGate()
{
foreach (var item in implementations)
{
try { item.CloseGate(); } catch (NotSupportedException) {}
}
throw new NotSupportedException();
}
public virtual void MoveToStart()
{
foreach (var item in implementations)
{
try { item.MoveToStart(); } catch (NotSupportedException) {}
}
throw new NotSupportedException();
}
}
You can create a base implementation of Axis to make sure all default implementations throw the exception. Derived implementations implement specific functionality.
You can then use it by simply calling
IAxis myAxis = new AxisProxy(new GateAxis(), new XAxis());
NOTE: In this case I would seriously consider changing the types to 'bool'; if you call these methods frequently, exception performance will add up... Also, since the NotSupportedException is not going to change, you can keep a per-method list to remove implementations that throw.

Factory pattern in C#: How to ensure an object instance can only be created by a factory class?

Recently I've been thinking about securing some of my code. I'm curious how one could make sure an object can never be created directly, but only via some method of a factory class. Let us say I have some "business object" class and I want to make sure any instance of this class will have a valid internal state. In order to achieve this I will need to perform some check before creating an object, probably in its constructor. This is all okay until I decide I want to make this check be a part of the business logic. So, how can I arrange for a business object to be creatable only through some method in my business logic class but never directly? The first natural desire to use a good old "friend" keyword of C++ will fall short with C#. So we need other options...
Let's try some example:
public MyBusinessObjectClass
{
public string MyProperty { get; private set; }
public MyBusinessObjectClass (string myProperty)
{
MyProperty = myProperty;
}
}
public MyBusinessLogicClass
{
public MyBusinessObjectClass CreateBusinessObject (string myProperty)
{
// Perform some check on myProperty
if (true /* check is okay */)
return new MyBusinessObjectClass (myProperty);
return null;
}
}
It's all okay until you remember you can still create MyBusinessObjectClass instance directly, without checking the input. I would like to exclude that technical possibility altogether.
So, what does the community think about this?
You can make the constructor private, and the factory a nested type:
public class BusinessObject
{
private BusinessObject(string property)
{
}
public class Factory
{
public static BusinessObject CreateBusinessObject(string property)
{
return new BusinessObject(property);
}
}
}
This works because nested types have access to the private members of their enclosing types. I know it's a bit restrictive, but hopefully it'll help...
Looks like you just want to run some business logic before creating the object - so why dont you just create a static method inside the "BusinessClass" that does all the dirty "myProperty" checking work, and make the constructor private?
public BusinessClass
{
public string MyProperty { get; private set; }
private BusinessClass()
{
}
private BusinessClass(string myProperty)
{
MyProperty = myProperty;
}
public static BusinessClass CreateObject(string myProperty)
{
// Perform some check on myProperty
if (/* all ok */)
return new BusinessClass(myProperty);
return null;
}
}
Calling it would be pretty straightforward:
BusinessClass objBusiness = BusinessClass.CreateObject(someProperty);
Or, if you want to go really fancy, invert control: Have the class return the factory, and instrument the factory with a delegate that can create the class.
public class BusinessObject
{
public static BusinessObjectFactory GetFactory()
{
return new BusinessObjectFactory (p => new BusinessObject (p));
}
private BusinessObject(string property)
{
}
}
public class BusinessObjectFactory
{
private Func<string, BusinessObject> _ctorCaller;
public BusinessObjectFactory (Func<string, BusinessObject> ctorCaller)
{
_ctorCaller = ctorCaller;
}
public BusinessObject CreateBusinessObject(string myProperty)
{
if (...)
return _ctorCaller (myProperty);
else
return null;
}
}
:)
You could make the constructor on your MyBusinessObjectClass class internal, and move it and the factory into their own assembly. Now only the factory should be able to construct an instance of the class.
After so many years this got asked, and all the answers I see are unfortunately telling you how you should do your code instead of giving a straight answer. The actual answer you were looking for is having your classes with a private constructor but a public instantiator, meaning that you can only create new instances from other existing instances... that are only available in the factory:
The interface for your classes:
public interface FactoryObject
{
FactoryObject Instantiate();
}
Your class:
public class YourClass : FactoryObject
{
static YourClass()
{
Factory.RegisterType(new YourClass());
}
private YourClass() {}
FactoryObject FactoryObject.Instantiate()
{
return new YourClass();
}
}
And, finally, the factory:
public static class Factory
{
private static List<FactoryObject> knownObjects = new List<FactoryObject>();
public static void RegisterType(FactoryObject obj)
{
knownObjects.Add(obj);
}
public static T Instantiate<T>() where T : FactoryObject
{
var knownObject = knownObjects.Where(x => x.GetType() == typeof(T));
return (T)knownObject.Instantiate();
}
}
Then you can easily modify this code if you need extra parameters for the instantiation or to preprocess the instances you create. And this code will allow you to force the instantiation through the factory as the class constructor is private.
Apart from what Jon suggested, you could also either have the factory method (including the check) be a static method of BusinessObject in the first place. Then, have the constructor private, and everyone else will be forced to use the static method.
public class BusinessObject
{
public static Create (string myProperty)
{
if (...)
return new BusinessObject (myProperty);
else
return null;
}
}
But the real question is - why do you have this requirement? Is it acceptable to move the factory or the factory method into the class?
Yet another (lightweight) option is to make a static factory method in the BusinessObject class and keep the constructor private.
public class BusinessObject
{
public static BusinessObject NewBusinessObject(string property)
{
return new BusinessObject();
}
private BusinessObject()
{
}
}
So, it looks like what I want cannot be done in a "pure" way. It's always some kind of "call back" to the logic class.
Maybe I could do it in a simple way, just make a contructor method in the object class first call the logic class to check the input?
public MyBusinessObjectClass
{
public string MyProperty { get; private set; }
private MyBusinessObjectClass (string myProperty)
{
MyProperty = myProperty;
}
pubilc static MyBusinessObjectClass CreateInstance (string myProperty)
{
if (MyBusinessLogicClass.ValidateBusinessObject (myProperty)) return new MyBusinessObjectClass (myProperty);
return null;
}
}
public MyBusinessLogicClass
{
public static bool ValidateBusinessObject (string myProperty)
{
// Perform some check on myProperty
return CheckResult;
}
}
This way, the business object is not creatable directly and the public check method in business logic will do no harm either.
In a case of good separation between interfaces and implementations the
protected-constructor-public-initializer pattern allows a very neat solution.
Given a business object:
public interface IBusinessObject { }
class BusinessObject : IBusinessObject
{
public static IBusinessObject New()
{
return new BusinessObject();
}
protected BusinessObject()
{ ... }
}
and a business factory:
public interface IBusinessFactory { }
class BusinessFactory : IBusinessFactory
{
public static IBusinessFactory New()
{
return new BusinessFactory();
}
protected BusinessFactory()
{ ... }
}
the following change to BusinessObject.New() initializer gives the solution:
class BusinessObject : IBusinessObject
{
public static IBusinessObject New(BusinessFactory factory)
{ ... }
...
}
Here a reference to concrete business factory is needed to call the BusinessObject.New() initializer. But the only one who has the required reference is business factory itself.
We got what we wanted: the only one who can create BusinessObject is BusinessFactory.
public class HandlerFactory: Handler
{
public IHandler GetHandler()
{
return base.CreateMe();
}
}
public interface IHandler
{
void DoWork();
}
public class Handler : IHandler
{
public void DoWork()
{
Console.WriteLine("hander doing work");
}
protected IHandler CreateMe()
{
return new Handler();
}
protected Handler(){}
}
public static void Main(string[] args)
{
// Handler handler = new Handler(); - this will error out!
var factory = new HandlerFactory();
var handler = factory.GetHandler();
handler.DoWork(); // this works!
}
I don't understand why you want to separate the "business logic" from the "business object". This sounds like a distortion of object orientation, and you'll end up tying yourself in knots by taking that approach.
I'd put the factory in the same assembly as the domain class, and mark the domain class's constructor internal. This way any class in your domain may be able to create an instance, but you trust yourself not to, right? Anyone writing code outside of the domain layer will have to use your factory.
public class Person
{
internal Person()
{
}
}
public class PersonFactory
{
public Person Create()
{
return new Person();
}
}
However, I must question your approach :-)
I think that if you want your Person class to be valid upon creation you must put the code in the constructor.
public class Person
{
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
Validate();
}
}
This solution is based off munificents idea of using a token in the constructor. Done in this answer make sure object only created by factory (C#)
public class BusinessObject
{
public BusinessObject(object instantiator)
{
if (instantiator.GetType() != typeof(Factory))
throw new ArgumentException("Instantiator class must be Factory");
}
}
public class Factory
{
public BusinessObject CreateBusinessObject()
{
return new BusinessObject(this);
}
}
Multiple approaches with different tradeoffs have been mentioned.
Nesting the factory class in the privately constructed class only allows the factory to construct 1 class. At that point you're better off with a Create method and a private ctor.
Using inheritance and a protected ctor has the same issue.
I'd like to propose the factory as a partial class that contains private nested classes with public constructors. You're 100% hiding the object your factory is constructing and only exposing what you choose to through one or multiple interfaces.
The use case I heard for this would be when you want to track 100% of instances in the factory. This design guarantees no one but the factory has access to creating instances of "chemicals" defined in the "factory" and it removes the need for a separate assembly to achieve that.
== ChemicalFactory.cs ==
partial class ChemicalFactory {
private ChemicalFactory() {}
public interface IChemical {
int AtomicNumber { get; }
}
public static IChemical CreateOxygen() {
return new Oxygen();
}
}
== Oxygen.cs ==
partial class ChemicalFactory {
private class Oxygen : IChemical {
public Oxygen() {
AtomicNumber = 8;
}
public int AtomicNumber { get; }
}
}
== Program.cs ==
class Program {
static void Main(string[] args) {
var ox = ChemicalFactory.CreateOxygen();
Console.WriteLine(ox.AtomicNumber);
}
}
I don't think there is a solution that's not worse than the problem , all he above require a public static factory which IMHO is a worse problem and wont stop people just calling the factory to use your object - it doesnt hide anything . Best to expose an interface and/or keep the constructor as internal if you can that's the best protection since the assembly is trusted code.
One option is to have a static constructor which registers a factory somewhere with something like an IOC container.
Here is another solution in the vein of "just because you can doesn't mean you should" ...
It does meet the requirements of keeping the business object constructor private and putting the factory logic in another class. After that it gets a bit sketchy.
The factory class has a static method for creating business objects. It derives from the business object class in order to access a static protected construction method that invokes the private constructor.
The factory is abstract so you can't actually create an instance of it (because it would also be a business object, so that would be weird), and it has a private constructor so client code can't derive from it.
What's not prevented is client code also deriving from the business object class and calling the protected (but unvalidated) static construction method. Or worse, calling the protected default constructor we had to add to get the factory class to compile in the first place. (Which incidentally is likely to be a problem with any pattern that separates the factory class from the business object class.)
I'm not trying to suggest anyone in their right mind should do something like this, but it was an interesting exercise. FWIW, my preferred solution would be to use an internal constructor and the assembly boundary as the guard.
using System;
public class MyBusinessObjectClass
{
public string MyProperty { get; private set; }
private MyBusinessObjectClass(string myProperty)
{
MyProperty = myProperty;
}
// Need accesible default constructor, or else MyBusinessObjectFactory declaration will generate:
// error CS0122: 'MyBusinessObjectClass.MyBusinessObjectClass(string)' is inaccessible due to its protection level
protected MyBusinessObjectClass()
{
}
protected static MyBusinessObjectClass Construct(string myProperty)
{
return new MyBusinessObjectClass(myProperty);
}
}
public abstract class MyBusinessObjectFactory : MyBusinessObjectClass
{
public static MyBusinessObjectClass CreateBusinessObject(string myProperty)
{
// Perform some check on myProperty
if (true /* check is okay */)
return Construct(myProperty);
return null;
}
private MyBusinessObjectFactory()
{
}
}
Would appreciate hearing some thoughts on this solution.
The only one able to create 'MyClassPrivilegeKey' is the factory. and 'MyClass' requires it in the constructor.
Thus avoiding reflection on private contractors / "registration" to the factory.
public static class Runnable
{
public static void Run()
{
MyClass myClass = MyClassPrivilegeKey.MyClassFactory.GetInstance();
}
}
public abstract class MyClass
{
public MyClass(MyClassPrivilegeKey key) { }
}
public class MyClassA : MyClass
{
public MyClassA(MyClassPrivilegeKey key) : base(key) { }
}
public class MyClassB : MyClass
{
public MyClassB(MyClassPrivilegeKey key) : base(key) { }
}
public class MyClassPrivilegeKey
{
private MyClassPrivilegeKey()
{
}
public static class MyClassFactory
{
private static MyClassPrivilegeKey key = new MyClassPrivilegeKey();
public static MyClass GetInstance()
{
if (/* some things == */true)
{
return new MyClassA(key);
}
else
{
return new MyClassB(key);
}
}
}
}

Categories

Resources