We have the following class hierarchy:
public interface IManager {
object GetObject(int);
}
public class BaseManager : IManager ...
public class XManager : BaseManager {
...
public static XManager Instance;
}
public class YManager : BaseManager {
...
public static YManager Instance;
}
public static class ManagerFacade {
private static IManager GetManager(type);
public static object GetObject(type, int) {
return GetManager(type).GetObject(int); }
}
How would you implement the GetManager() function?
Is it possible to collect these types and their instances (or instance creating delegates) in a static dictionary in the static constructors of these classes?
(Thank you Jon, I only remembered "something is different in .Net 4", but not the details)
Other ways would use class attributes or descendents of BaseManager or looking for implementations of IManager.
What is the preferred solution?
The fact that static members are involved makes me think that a dictionary-based approach is the best, unless you want to invoke reflection and figure out the method for retrieving the singleton. This is a working sample code I was able to come up with:
// Added another interface - GetInstance
public interface IManager
{
object GetObject(int i);
}
// made BaseManager abstract; you don't have to do that, but then
// remember to make everything virtual, etc etc.
public abstract class BaseManager : IManager
{
public abstract object GetObject(int i);
}
The child classes each implement a static constructor to create the singleton instance in my example, which is way too simplistic, but I'm sure you have a better way to do this:
public class XManager : BaseManager
{
public static XManager Instance;
static XManager() { Instance = new XManager(); }
public override object GetObject(int i)
{
return "XManager Instance: index was " + i.ToString();
}
}
public class YManager : BaseManager
{
public static YManager Instance;
static XManager() { Instance = new YManager(); }
public override object GetObject(int i)
{
return "YManager Instance: index was " + i.ToString();
}
}
The ManagerFacade would implement the dictionary this way:
public static class ManagerFacade
{
private static readonly Dictionary<Type, IManager> managerInstances
= new Dictionary<Type, IManager>()
{
{typeof(XManager), XManager.Instance},
{typeof(YManager), YManager.Instance}
};
private static IManager GetManager<T>() where T: IManager
{
return managerInstances[typeof(T)];
}
public static object GetObject<T>(int i) where T: IManager
{
return GetManager<T>().GetObject(i);
}
}
The console app to test out the manager facade:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ManagerFacade.GetObject<XManager>(2).ToString());
Console.WriteLine(ManagerFacade.GetObject<YManager>(4).ToString());
// pause program execution to review results...
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
Console output:
XManager Instance: index was 2
YManager Instance: index was 4
Press enter to exit
I'm sure that there's more elegant ways to do this, but I just wanted to illustrate how to set up and access the dictionary to support the singletons.
I think the most common approach is to use something like IServiceProvider.
The best approach for this depends on the usage you expect. If you have only a few managers, and you expect to increase the number only occasionally, then I would go with the straightforward approach:
class ManagerFacade {
XManager getXManager() {...}
....
}
This reduces errors be making sure that the caller always gets the type of manager they are expecting. However it does mean you need to change ManagerFacade every time you add a type of manager, so it's not appropriate in those cases.
If you need to add new managers fairly frequently then implement
class ManagerFacade {
IManager getManager(type) {...}
....
}
hardcoding the logic behind getManager() and using an enum or equivalent as the type. This means you need to rewrite the method when you add a manager, but the interface doesn't change.
If your managers are changing frequently or dynamically then keep a dictionary behind the scenes which you populate with the appropriate managers. Use a String as 'type', so that you don't have to change an 'enum' class when you add a manager. You can lazily initialise the managers if you need to.
Incidentally, are you sure you need a singleton here? Just because you want to have ManagerFacade always return the same instance of XManager doesn't mean XManager needs to be a Singleton. You can make XManager internal to ManagerFacade, or restrict the manager creation to be done through a static method.
Related
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.
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);
}
Is it possible to specify that members of a nested class can be accessed by the enclosing class, but not other classes ?
Here's an illustration of the problem (of course my actual code is a bit more complex...) :
public class Journal
{
public class JournalEntry
{
public JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
// ...
}
I would like to prevent client code from creating instances of JournalEntry, but Journal must be able to create them. If I make the constructor public, anyone can create instances... but if I make it private, Journal won't be able to !
Note that the JournalEntry class must be public, because I want to be able to expose existing entries to client code.
Any suggestion would be appreciated !
UPDATE: Thanks everyone for your input, I eventually went for the public IJournalEntry interface, implemented by a private JournalEntry class (despite the last requirement in my question...)
Actually there is a complete and simple solution to this problem that doesn't involve modifying the client code or creating an interface.
This solution is actually faster than the interface-based solution for most cases, and easier to code.
public class Journal
{
private static Func<object, JournalEntry> _newJournalEntry;
public class JournalEntry
{
static JournalEntry()
{
_newJournalEntry = value => new JournalEntry(value);
}
private JournalEntry(object value)
{
...
If your class is not too complex, you could either use an interface which is publicly visible and make the actual implementing class private, or you could make a protected constructor for the JornalEntry class and have a private class JornalEntryInstance derived from JornalEntry with a public constructor which is actually instantiated by your Journal.
public class Journal
{
public class JournalEntry
{
protected JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
private class JournalEntryInstance: JournalEntry
{
public JournalEntryInstance(object value): base(value)
{ }
}
JournalEntry CreateEntry(object value)
{
return new JournalEntryInstance(value);
}
}
If your actual class is too complex to do either of that and you can get away with the constructor being not completely invisible, you can make the constructor internal so it is only visible in the assembly.
If that too is infeasible, you can always make the constructor private and use reflection to call it from your journal class:
typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });
Now that I think about it, another possibility would use a private delegate in the containing class which is set from the inner class
public class Journal
{
private static Func<object, JournalEntry> EntryFactory;
public class JournalEntry
{
internal static void Initialize()
{
Journal.EntryFactory = CreateEntry;
}
private static JournalEntry CreateEntry(object value)
{
return new JournalEntry(value);
}
private JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
static Journal()
{
JournalEntry.Initialize();
}
static JournalEntry CreateEntry(object value)
{
return EntryFactory(value);
}
}
This should give you your desired visibility levels without needing to resort on slow reflection or introducing additional classes / interfaces
Make JournalEntry a private nested type. Any public members will be visible only to the enclosing type.
public class Journal
{
private class JournalEntry
{
}
}
If you need to make JournalEntry objects available to other classes, expose them via a public interface:
public interface IJournalEntry
{
}
public class Journal
{
public IEnumerable<IJournalEntry> Entries
{
get { ... }
}
private class JournalEntry : IJournalEntry
{
}
}
A simpler approach is to just use an internal constructor, but make the caller prove who they are by supplying a reference that only the legitimate caller could know (we don't need to be concerned about non-public reflection, because if the caller has access to non-public reflection then we've already lost the fight - they can access a private constructor directly); for example:
class Outer {
// don't pass this reference outside of Outer
private static readonly object token = new object();
public sealed class Inner {
// .ctor demands proof of who the caller is
internal Inner(object token) {
if (token != Outer.token) {
throw new InvalidOperationException(
"Seriously, don't do that! Or I'll tell!");
}
// ...
}
}
// the outer-class is allowed to create instances...
private static Inner Create() {
return new Inner(token);
}
}
In this case you could either:
Make the constructor internal - this stops those outside this assembly creating new instances or...
Refactor the JournalEntry class to use a public interface and make the actual JournalEntry class private or internal. The interface can then be exposed for collections while the actual implementation is hidden.
I mentioned internal as a valid modifier above however depending on your requirements, private may be the better suited alternative.
Edit: Sorry I mentioned private constructor but you've already dealt with this point in your question. My apologies for not reading it correctly!
For generic nested class =)
I know this is an old question and it has already an accepted answer, nevertheless for those google swimmers who may have a similar scenario to mine this answer may provide some help.
I came across this question for I needed to implement the same feature as the OP. For my first scenario this and this answers worked just fine. Nevertheless I needed also to expose a nested generic class. The problem is that you can not expose a delegate type field (the factory field) with opened generic parameters without making your own class generic, but obviously this is not what we want, so, here is my solution for such scenario:
public class Foo
{
private static readonly Dictionary<Type, dynamic> _factories = new Dictionary<Type, dynamic>();
private static void AddFactory<T>(Func<Boo<T>> factory)
=> _factories[typeof(T)] = factory;
public void TestMeDude<T>()
{
if (!_factories.TryGetValue(typeof(T), out var factory))
{
Console.WriteLine("Creating factory");
RuntimeHelpers.RunClassConstructor(typeof(Boo<T>).TypeHandle);
factory = _factories[typeof(T)];
}
else
{
Console.WriteLine("Factory previously created");
}
var boo = (Boo<T>)factory();
boo.ToBeSure();
}
public class Boo<T>
{
static Boo() => AddFactory(() => new Boo<T>());
private Boo() { }
public void ToBeSure() => Console.WriteLine(typeof(T).Name);
}
}
We have Boo as our internal nested class with a private constructor and we mantain on our parent class a dictionary with these generic factories taking advantage of dynamic. So, each time TestMeDude is called, Foo searches for whether the factory for T has already been created, if not it creates it calling nested class' static constructor.
Testing:
private static void Main()
{
var foo = new Foo();
foo.TestMeDude<string>();
foo.TestMeDude<int>();
foo.TestMeDude<Foo>();
foo.TestMeDude<string>();
Console.ReadLine();
}
The output is:
The solution Grizzly suggested does make it a bit hard to create the nested class somewhere else but not impossible,like Tim Pohlmann wrote someone can still inherit it and use the inheriting class ctor.
I'm taking advantage of the fact that nested class can access the container private properties, so the container asks nicely and the nested class gives access to the ctor.
public class AllowedToEmailFunc
{
private static Func<long, EmailPermit> CreatePermit;
public class EmailPermit
{
public static void AllowIssuingPermits()
{
IssuegPermit = (long userId) =>
{
return new EmailPermit(userId);
};
}
public readonly long UserId;
private EmailPermit(long userId)
{
UserId = userId;
}
}
static AllowedToEmailFunc()
{
EmailPermit.AllowIssuingPermits();
}
public static bool AllowedToEmail(UserAndConf user)
{
var canEmail = true; /// code checking if we can email the user
if (canEmail)
{
return IssuegPermit(user.UserId);
}
else
{
return null
}
}
}
This solution is not something I would do on a regular day on the job, not because it will lead to problems in other places but because it's unconventional (I've never seen it before) so it might cause other developers pain .
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.
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);
}
}
}
}