C# virtual (or abstract) static methods - c#

Static inheritance works just like instance inheritance. Except you are not allowed to make static methods virtual or abstract.
class Program {
static void Main(string[] args) {
TestBase.TargetMethod();
TestChild.TargetMethod();
TestBase.Operation();
TestChild.Operation();
}
}
class TestBase {
public static void TargetMethod() {
Console.WriteLine("Base class");
}
public static void Operation() {
TargetMethod();
}
}
class TestChild : TestBase {
public static new void TargetMethod() {
Console.WriteLine("Child class");
}
}
This will output:
Base class
Child class
Base class
Base class
But I want:
Base class
Child class
Base class
Child class
If it I could on static methods, I would make TargetMethod virtual and it would do the job. But is there a work around to get the same effect?
Edit: Yes, I could put a copy of Operation in the child class, but this would require copy and pasting a large bit of code into every child, which in my case is about 35 classes, a maintenance nightmare.

No, you cannot override a static method. "static" also means that it is statically bound by the compiler, so the actual method to be called is not found at runtime, but bound at compile time.
What you should do is make the class non-static. Make the method virtual and override it and make full benefit of real inheritance. Then, if you really need it, make a static entry point to a reference of your class. For instance a static factory, singleton (it's an anti-pattern in most of the cases but is as good as a static class) or just a static property.

You could store the TargetMethod as a delegate, which a subclass could change as needed:
class TestBase {
protected static Action _targetMethod;
static new() {
_targetMethod = new Action(() => {
Console.WriteLine("Base class");
});
}
public static void TargetMethod() {
_targetMethod();
}
public static void Operation() {
TargetMethod();
}
}
class TestChild : TestBase {
static new() {
_targetMethod = new Action(() => {
Console.WriteLine("Child class");
});
}
}
Since these are static instances, though - the _targetMethod is shared across all instances - changing it in TestChild changes it for TestBase as well. You may or may not care about that. If you do, generics or a Dictionary<Type, Action> might help.
Overall, though, you'd have a much easier time if you didn't insist on statics, or perhaps used composition instead of inheritance.

If you are looking to do abstract static methods, then this works, and turns out to be the easiest solution for me to adapt to:
class TestBase<ChildType> where ChildType : TestBase<ChildType> {
//public static abstract void TargetMethod();
public static void Operation() {
typeof(ChildType).GetMethod("TargetMethod").Invoke(null, null);
}
}
class TestChild : TestBase<TestChild> {
public static void TargetMethod() {
Console.WriteLine("Child class");
}
}
But I am still marking Stafan as the solution because using instance inheritance is probably the best recommendation for anyone in a similar situation. But I simply would have to rewrite too much code for it.

Ok here is what I have done
public abstract class Base<T>
where T : Base<T>, new()
{
#region Singleton Instance
//This is to mimic static implementation of non instance specific methods
private static object lockobj = new Object();
private static T _Instance;
public static T Instance
{
get
{
if (_Instance == null)
{
lock (lockobj)
{
if (_Instance == null)
{
_Instance = new T();
}
}
}
return _Instance;
}
}
#endregion //Singleton Instance
#region Abstract Definitions
public abstract T GetByID(long id);
public abstract T Fill(SqlDataReader sr);
#endregion //Abstract Definitions
}
public class InstanceClass : Base<InstanceClass>
{
//empty constructor to ensure you just get the method definitions without any
//additional code executing
public InstanceClass() { }
#region Base Methods
public override InstanceClass GetByID(long id)
{
SqlDataReader sr = DA.GetData("select * from table");
return InstanceClass.Instance.Fill(sr);
}
internal override InstanceClass Fill(SqlDataReader sr)
{
InstanceClass returnVal = new InstanceClass();
returnVal.property = sr["column1"];
return returnVal;
}
}
I think this will be a viable solution for what you want to do without breaking too many purist OO principles.

Related

Force a child class to pass itself as the Generic parameter to the base class

I want to force my child classes to pass themselves as as the generic parameter to the parent class.
For example :
class BaseClass<T> where T: BaseClass
{
//FullClassName : Tuple [Save,Update,Delete]
Dictionary<string,Tuple<delegate,delegate,delegate>> dict = new Dictionary...;
static BaseClass()
{
RegisterType();
}
private static void RegisterType()
{
Type t = typeof(T);
var props = t.GetProperties().Where(/* Read all properties with the SomeCustomAttribute */);
/* Create the delegates using expression trees and add the final tuple to the dictionary */
}
public virtual void Save()
{
delegate d = dict[t.GetType().FullName];
d.Item1(this);
}
}
class ChildClass : BaseClass<ChildClass>
{
[SomeCustomAttribute]
public int SomeID {get;set;}
[SomeCustomAttribute]
public string SomeName {get; set;}
}
public class Program
{
public static void Main(string[] args)
{
ChildClass c = new ChildClass();
c.Save();
}
}
Obviously the above code won't compile. I'll restate : I want the child class to pass itself as the generic parameter and not any other child of BaseClass.
(The above code is kind of a psuedo code and will still not compile).
You can do this:
public class BaseClass<T> where T: BaseClass<T> { }
public class ChildClass : BaseClass<ChildClass> { }
But this doesn't force you to use ChildClass as the generic parameter. You could do this public class OtherChildClass : BaseClass<ChildClass> { } which would break the "coontract" that you want to enforce.
The direct answer is that if your accessing a static method then typeof(T) will give you the type for reflection.
However, there is probably better solutions than using reflection. Options:
1) Static constructor on the child class.
2) Abstract method declared in the base class.
I do not know the application, but I get concerned about my design if I feel like using a static constructor, I also get concerned if a base class needs to initialize the child class.
I suggest looking at injection as a solution rather than inheritance. It offers superior unit testing and often a better architecture.
More info (after initial post), this is my preferred solution:
public interface IRegesterable
{
void Register();
}
public class Widget : IRegesterable
{
public void Register()
{
// do stuff
}
}
public class Class1
{
public Class1(IRegesterable widget)
{
widget.Register();
}
}
Hope this helps
The ConcurrentDictionary is being used as a Set<Type>. We can check in the Set<Type> if the type has been initialized. If not we run RegisterType on the type.
public abstract class BaseClass
{
//Concurrent Set does not exist.
private static ConcurrentDictionary<Type, bool> _registeredTypes
= new ConcurrentDictionary<Type, bool>();
protected BaseClass()
{
_registeredTypes.GetOrAdd(GetType(), RegisterType);
}
private static bool RegisterType(Type type)
{
//some code that will perform one time processing using reflections
//dummy return value
return true;
}
}
public class ChildClass : BaseClass
{
}
There are several inefficiencies with this pattern though.
object.GetType() is pretty darn slow, and inefficient.
Even with the HashSet behavior, we are checking for initialization on each instanciation. Its as fast as I can get it, but its still pretty superfluous.

How to make a class factory to create the required derived class

I often use the class-factory pattern whereby a class has a private constructor and a static method to create the class. This allows for the situation where the class cannot be constructed for some reason, and a null is returned - very handy.
I would like to be able to extend this to a factory method which creates a particular class from a hierarchy of derived classes depending on conditions. However I can't see a way of then hiding the constructors of the derived classes to force the use of the factory method. If the factory method is in the base class it no longer has access to the private constructors of derived classes. Putting a factory method in every derived class doesn't work as the required type must then be known beforehand. Nested classes might be a way if a class had access to the private members of a nested class, but sadly it seems that the nested classes have access to the private members of the enclosing class, but not the other way round.
Does anyone know of a way of doing this?
There are several possibilities, two of which are:
Put all those classes in one project and make the constructors internal. Other projects won't be able to call those constructors but the code inside that project can.
Make the constructors of those classes protected (instead of private) and create a private derived class in the class containing the factory method. Create an instance of that private class and return it.
Example for the second option:
public static class AnimalFactory
{
public static Animal Create(int parameter)
{
switch(parameter)
{
case 0:
return new DogProxy();
case 1:
return new CatProxy();
default:
throw new ArgumentOutOfRangeException("parameter");
}
}
private class DogProxy : Dog { }
private class CatProxy : Cat { }
}
public abstract class Animal { }
public class Dog : Animal
{
protected Dog() { }
}
public class Cat : Animal
{
protected Cat() { }
}
Here's the sample code I was working on when Daniel posted his answer. It looks like it's doing what he suggested:
public static class BaseFactory
{
public static Base Create(bool condition)
{
if (condition)
{
return Derived1.Create(1, "TEST");
}
else
{
return Derived2.Create(1, DateTime.Now);
}
}
}
public class Base
{
protected Base(int value)
{
}
protected static Base Create(int value)
{
return new Base(value);
}
}
public sealed class Derived1: Base
{
private Derived1(int value, string text): base(value)
{
}
internal static Derived1 Create(int value, string text)
{
return new Derived1(value, text);
}
}
public sealed class Derived2: Base
{
private Derived2(int value, DateTime time): base(value)
{
}
internal static Derived2 Create(int value, DateTime time)
{
return new Derived2(value, time);
}
}
[EDIT] And for Daniel's second suggestion:
public static class BaseFactory
{
public static Base Create(bool condition)
{
if (condition)
{
return new Derived1Creator(1, "TEST");
}
else
{
return new Derived2Creator(1, DateTime.Now);
}
}
private sealed class Derived1Creator: Derived1
{
public Derived1Creator(int value, string text): base(value, text)
{
}
}
private sealed class Derived2Creator: Derived2
{
public Derived2Creator(int value, DateTime time): base(value, time)
{
}
}
}
public class Base
{
protected Base(int value)
{
}
protected static Base Create(int value)
{
return new Base(value);
}
}
public class Derived1: Base
{
protected Derived1(int value, string text): base(value)
{
}
protected static Derived1 Create(int value, string text)
{
return new Derived1(value, text);
}
}
public class Derived2: Base
{
protected Derived2(int value, DateTime time): base(value)
{
}
protected static Derived2 Create(int value, DateTime time)
{
return new Derived2(value, time);
}
}
Note that this second approach means that the classes can't be sealed, unfortunately.
Rather than using methods inside the class itself as a factory implement the Factory pattern by means of a static class ("the factory") that returns the correct instance based on the logic you write.
You can intercept the derived type creation in the base class contructor and check that the caller is your factory using StackFrames:
protected Class1() //base class ctor
{
StackFrame[] stackFrames = new StackTrace().GetFrames();
foreach (var frame in stackFrames)
{
//check caller and throw an exception if not satisfied
}
}

Static/singleton interface implementing class in C#

i have a class that (right now) is static:
public static class Grob
{
public static void Frob()
{
Foo.Bar();
}
}
And that works well. Code calls:
Grob.Frob();
and all is right with the world. Now i want my class to implement an interface:
public static class Grob : IOldNewGrob
{
public static void Frob()
{
Foo.Bar();
}
}
Unfortunately that does not work, because reasons.
So i would try changing to class to a singleton:
public sealed class Grob
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Grob() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
Which works well enough, except that it doesn't work - the code no longer compiles:
Grob.Frob();
In other languages it would not be a problem. i would create a global Grob function (called Grob because that's the name that existing code needs):
function Grob(): GrobSingleton;
{
return Grob.Instance;
}
//and rename Grob class to something else
public sealed class GrobSinglton
{
...
}
except that C# doesn't have global functions.
In the end:
i don't need a global function
i don't need a static class to be able to implement an interface
i don't need a singleton
i just want it all to work.
Why not just create a singleton which also has a static Frob method?
public sealed class Grob : IOldNewGrob
{
private static readonly Grob instance = new Grob();
public static Grob Instance { get { return instance; } }
// Prevent external instantiation
private Grob() {}
public static void Frob()
{
Foo.Bar();
}
// Implement IOldNewGrob here
}
You should probably also read my article on implementing the singleton pattern in .NET - there's really no need to implement the fragile double-checked locking pattern.
That satisfies both of your requirements of making Grob.Frob() work, and making Grob implement an interface. It's not clear whether those are your only requirements though - you haven't really explained why you're trying to do that - where the singleton or the interface come in.
EDIT: If the idea was that Frob was a member of IOldNewGrob, you can use explicit interface implementation like this:
public sealed class Grob : IOldNewGrob
{
private static readonly Grob instance = new Grob();
public static Grob Instance { get { return instance; } }
// Prevent external instantiation
private Grob() {}
public static void Frob()
{
// Implementation
}
// Explicit interface implementation to prevent name collisions
void IOldNewGrob.Frob()
{
// Call the static implementation
Frob();
}
}

What's the best way to ensure a base class's static constructor is called?

The documentation on static constructors in C# says:
A static constructor is used to
initialize any static data, or to
perform a particular action that needs
performed once only. It is called
automatically before the first
instance is created or any static
members are referenced.
That last part (about when it is automatically called) threw me for a loop; until reading that part I thought that by simply accessing a class in any way, I could be sure that its base class's static constructor had been called. Testing and examining the documentation have revealed that this is not the case; it seems that the static constructor for a base class is not guaranteed to run until a member of that base class specifically is accessed.
Now, I guess in most cases when you're dealing with a derived class, you would construct an instance and this would constitute an instance of the base class being created, thus the static constructor would be called. But if I'm only dealing with static members of the derived class, what then?
To make this a bit more concrete, I thought that the code below would work:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I assumed that accessing the Type<T> class would automatically invoke the static constructor for TypeBase; but this appears not to be the case. Type<int>.Name is null, and the code above outputs the empty string.
Aside from creating some dummy member (like a static Initialize() method that does nothing), is there a better way to ensure that a base type's static constructor will be called before any of its derived types is used?
If not, then... dummy member it is!
You may call static constructor explicity, so you will not have to create any methods for initialization:
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof (TypeBase).TypeHandle);
You may call it in static constructor of derived class.
As others have noted, your analysis is correct. The spec is implemented quite literally here; since no member of the base class has been invoked and no instance has been created, the static constructor of the base class is not called. I can see how that might be surprising, but it is a strict and correct implementation of the spec.
I don't have any advice for you other than "if it hurts when you do that, don't do that." I just wanted to point out that the opposite case can also bite you:
class Program
{
static void Main(string[] args)
{
D.M();
}
}
class B
{
static B() { Console.WriteLine("B"); }
public static void M() {}
}
class D: B
{
static D() { Console.WriteLine("D"); }
}
This prints "B" despite the fact that "a member of D" has been invoked. M is a member of D solely by inheritance; the CLR has no way of distinguishing whether B.M was invoked "through D" or "through B".
The rules here are very complex, and between CLR 2.0 and CLR 4.0 they actually changed in subtle and interesting ways, that IMO make most "clever" approaches brittle between CLR versions. An Initialize() method also might not do the job in CLR 4.0 if it doesn't touch the fields.
I would look for an alternative design, or perhaps use regular lazy initialization in your type (i.e. check a bit or a reference (against null) to see if it has been done).
In all of my testing, I was only able to get a call to a dummy member on the base to cause the base to call its static constructor as illustrated:
class Base
{
static Base()
{
Console.WriteLine("Base static constructor called.");
}
internal static void Initialize() { }
}
class Derived : Base
{
static Derived()
{
Initialize(); //Removing this will cause the Base static constructor not to be executed.
Console.WriteLine("Derived static constructor called.");
}
public static void DoStaticStuff()
{
Console.WriteLine("Doing static stuff.");
}
}
class Program
{
static void Main(string[] args)
{
Derived.DoStaticStuff();
}
}
The other option was including a static read-only member in the derived typed that did the following:
private static readonly Base myBase = new Base();
This however feels like a hack (although so does the dummy member) just to get the base static constructor to be called.
I almost alway regret relying on something like this. Static methods and classes can limit you later on. If you wanted to code some special behavior for your Type class later you would be boxed in.
So here is a slight variation on your approach. It is a bit more code but it will allow you to have a custom Type defined later that lets you do custom things.
abstract class TypeBase
{
private static bool _initialized;
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new Type<int> {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
}
class Type<T> : TypeBase
{
private static Type<T> _instance;
public static Type<T> Instance
{
get
{
Initialize();
return _instance;
}
internal set { _instance = value; }
}
public string Name { get; internal set; }
}
Then later when you get to adding a virtual method to Type and want a special implementation for Type you can implement thus:
class TypeInt : Type<int>
{
public override string Foo()
{
return "Int Fooooo";
}
}
And then hook it up by changing
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new TypeInt {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
My advice would be to avoid static constructors - it is easy to do. Also avoid static classes and where possible static members. I am not saying never, just sparingly. Prefer a singleton of a class to a static.
Just an idea, you can do something like this:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
static Type()
{
new Type<object>();
}
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}

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