Apologies for the title, I really don't know what to call this problem. I have an abstract class which describes the interface of some data collection. I would like to retrieve an instance list of all classes that derives from this, without littering the base class or the code that uses it with references to the new type name. In effect, I want to be able to add new derived classes of the base and the rest of the code should work unaffected.
Maybe some code will help illustrate the problem:
public abstract class BaseData
{
public static List<BaseData> getCollection()
{
return collection;
}
static private List<BaseData> collection = new List<BaseData>();
// the actual part of the interface.
public abstract int[] getSomeData();
protected BaseData()
{
// when some derived class is statically created, they get added to the static list.
collection.Add(this);
}
}
And then I can use the interface like this:
// some actual code file:
class App
{
public App()
{
foreach(var dataimpl in BaseData.getCollection())
{
//.. do something here.
var data = dataimpl.getSomeData();
}
}
}
The idea is, that I can now add new cases to this data collection in another file, without altering the other two pieces of code, like so:
// hidden implementation classes
class SomeImplementation1 : BaseData
{
// register the class in the base class list
static private SomeImplementation1 register = new SomeImplementation1();
public override int[] getSomeData() { return null; }
private SomeImplementation1() { }
}
class SomeImplementation2 : BaseData
{
// register the class in the base class list
static private SomeImplementation2 register = new SomeImplementation2();
public override int[] getSomeData() { return null; }
private SomeImplementation2() { }
}
The use cases are many, tests, data and such. The problem, however, is, that the static register variable in the child classes isn't actually instantiated (and thus, the parent constructor is not run, which in turn means the class is not registered in the collection) before the child class is referenced - that is, the static initializers will not run before an instance is created.
This then requires me to reference the child classes somewhere in a list, which defeats the whole purpose of this system. My question is, is this a common pattern - is there an existing solution or a somehow similar implementation to this - or can this code be fixed somehow?
Thanks
Get rid of the "abstract class which describes the interface" and use an actual interface.
interface IHaveData
{
int[] getSomeData();
}
Now this frees you up to implement registrations however you want. Here's one simple way that fits with your initial code:
class BaseData
{
private static readonly List<IHaveData> collection = new List<IHaveData>();
public static IEnumerable<IHaveData> getCollection()
{
return collection;
}
public static void Register(IHaveData instance)
{
collection.Add(instance);
}
}
class SomeImplementation1 : IHaveData
{
private static readonly SomeImplementation1 registration = new SomeImplementation1();
private SomeImplementation1()
{
BaseData.Register(this);
}
public int[] getSomeData() { return null; }
}
class SomeImplementation2 : IHaveData
{
private static readonly SomeImplementation2 registration = new SomeImplementation2();
private SomeImplementation2()
{
BaseData.Register(this);
}
public int[] getSomeData() { return null; }
}
UPDATE
You will need a container of some kind and manually register your instances or use reflection to instantiate your instances and add them to the container.
class SomeImplementation1 : IHaveData
{
public int[] getSomeData() { return null; }
}
class SomeImplementation2 : IHaveData
{
public int[] getSomeData() { return null; }
}
Manual Registration (Safest, but you do have to edit the registrations for each new implementation)
class BaseData
{
private static readonly List<IHaveData> collection = new List<IHaveData>
{
new SomeImplementation1(),
new SomeImplementation2()
//as you add more implementations, you'll need to add them here
};
public static IEnumerable<IHaveData> getCollection()
{
return collection;
}
}
Automatic Registration (No more editing registrations, but any constructor changes and you get runtime errors and tricky to debug)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
class BaseData
{
private static List<IHaveData> collection;
public static IEnumerable<IHaveData> getCollection()
{
if (collection == null)
{
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(type =>
type.IsClass &&
!type.IsAbstract &&
type.GetInterfaces().Any(i => i == typeof(IHaveData)));
//All implementation must have the same constructor signature. In this case, a parameterless constructor.
collection = new List<IHaveData>(types.Select(x => (IHaveData)Activator.CreateInstance(x)));
}
return collection;
}
}
Related
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();
}
}
With the code below, will each call to Test.someBaseField or Test.someBaseProperty result in the function being called and a new instance of SomeBase being created? or does that only happen once at the start?
How would I set it up for the latter (called once at the start)?
public class SomeBase {}
public class SomeObjectA : SomeBase {}
public class SomeObjectB : SomeBase {}
public class Test
{
public static bool someBool = true;
public static SomeBase someBaseField = GetBase(someBool);
public static SomeBase someBaseProperty { get { return GetBase(someBool); } }
public static SomeBase GetBase(bool getA)
{
if(getA)
return new SomeObjectA() as SomeBase;
else
return new SomeObjectB() as SomeBase;
}
}
Get base will be called each time for either property and a new instance of somebase will be returned every time. What you have going on there is called a factory.
What you are wanting to do is create a singleton. There are many methods to create singletons but the most popular is to track some field or property and return that every time if initialized or initialize it if not.
so you are looking at doing something like:
static someBase _trackingVar;
public static someBase someProperty{
get
{
if(_trackingVar == null){
_trackingVar = GetBase(...);
}
return _trackingVar;
}
}
The one problem with this approach is that it is not thread safe. There's a thread safe version of this approach to singleton creation. See http://msdn.microsoft.com/en-us/library/ff650316.aspx for more details
Each call to "new" would create a new instance of the class "SomeBase". So in your case, these two lines would create two new instances .
public static SomeBase someBaseField = GetBase(someBool);
public static SomeBase someBaseProperty { get { return GetBase(someBool); } }
Please note that, in both the cases , you are only making the references as static. static references have no impact on object creation.
If you want to create a single object only,
use a private filed :
private static SomeBase _someBaseField = null;
Add a null check in GetBase() like following :
if (_someBaseField == null)
{
_someBaseField = new SomeObjectA() as SomeBase;
return _someBaseField;
}
else
{
return _someBaseField;
}
optionally you can change the someBaseProperty, so that you can use the property setter internally too.
public static SomeBase someBaseProperty
{
get { return GetBase(someBool); }
private set(value) { _someBaseField = value; }
}
There is no need to expose the Filed as a public.
[MAJOR EDITS, my first post was somewhat misleading. My appologies]
Given a class such as:
public class DatabaseResult{
public bool Successful;
public string ErrorMessage;
//Database operation failed
public static DatabaseResult Failed(string message) {
return new DatabaseResult{
Successful = true,
ErrorMessage = message
};
}
}
How can I implement subclasses such that I can add additional properties to represent data relevant to the particular operation (such as MatchedResult in the case of a SELECT type query) without the need to implement that static failure function? If I try to use plain inheritance, the return type will be of the parent class. Eg:
DoThingDatabaseResult : DatabaseResult {
public IEnumerable<object> SomeResultSet;
public static Successful(IEnumerable<object> theResults){
return new DoThingDatabaseResult {
Successful = true,
ErrorMessage = "",
SomeResultSet = theResults
};
}
//public static DatabaseResult Failed exists, but it's the parent type!
}
The goal is to avoid needing to copy the Failed static function for every subclass implementation.
Make it recursively generic:
public class BankAccount<T> where T : BankAccount<T>, new()
{
public T SomeFactoryMethod() { return new T(); }
}
public class SavingsAccount: BankAccount<SavingsAccount>{}
You'll note that I made the factory method non-static, because static methods aren't inherited.
You can't do this exactly as you have defined the question. The best way to tackle this is really to pull your factory out of the class completely:
public class BankAccount
{
}
public class SavingsAccount : BankAccount
{
}
public static class BankAccountFactory
{
public static T Create<T>() where T : BankAccount, new()
{
return new T();
}
}
Now the Factory has no dependency on the actual type. You can pass any derived class of BankAccount and get it back without doing any extra work or worrying about inheriting your factory method.
If I may, I'd like to expand upon StriplingWarrior. In fact, you can use static for the factory. This following code shows that a and c are the expected object types. The limit is you cannot use the factory on the base class itself.
private void Testit()
{
var a = SavingsAccount.Factory();
var c = CheckingAccount.Factory();
//var b = BankAccount.Factory(); //can't do this
}
public class BankAccount<T> where T : BankAccount<T>, new()
{
public static T Factory()
{
return new T();
}
}
public class SavingsAccount : BankAccount<SavingsAccount>
{
}
public class CheckingAccount : BankAccount<CheckingAccount>
{
}
In order to use inheritance, you need an instance of an object and a member of that object. In this case, for the object we can't use BankAccount/SavingsAccount because then we would already have what we're trying to get. This means we need an actual factory object, which is what most people are talking about when they talk about a factory. So if we pull that out into a Factory and use inheritance...
public class BankAccountFactory { public virtual GetAccount() { return new BankAccount(); } }
public class SavingsAccountFactory : BankAccountFactory { public override GetAccount() { return new SavingsAccount(); } }
But now how do we get an instance of the proper type? We've just pushed our problem one layer deeper.
Instead, what you probably want to do, is use some sort of configuration to determine the type, or pass the type you want into a method.
public BankAccount GetAccount(AccountType type) { /* */ }
or
public BankAccount GetAccount() { /* Access config */ }
For a simple answer to your question: You don't need to use generics or anything like that, you just need your method to not be static...
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 .
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);
}
}
}
}