I have a configuration class store application configuration. Currently I am using a static class. Some of the configurations are related to one topic so I want to organize them into a nested class, so I can reference configurations like this:
AppConfig.Url
AppConfig.LogSettings.FileSize
I have two options, either use a static nested class,
public static class AppConfig
{
public static class LogSettings
{
public static int FileSize {get; set;}
}
}
or declare a class but add a static property:
public static class AppConfig
{
public class LogSettings
{
public int FileSize {get; set;}
}
public static LogSettings logSettings { get; private set; }
}
However, none of them can protect nested class member FileSize being modified by other classes, even I use private set to protect the public static property.
Maybe I should not use nested class to implement this? Any suggestions?
The other solutions given so far essentially require the property being set to be set once. I am very much in favour of immutable objects, but they are not always practical; is it possible to solve your problem and make the property mutable?
This is in fact a special case of the more general problem you pose: how can we mark certain members of an inner class as being accessible only to the outer class, but not to anything outside of that class?
It is by no means obvious how to do so, but this is surprisingly easy. The key to the solution is to remember that interfaces may be private implementation details. C# requires that a base class be at least as accessible as the class deriving from it, but C# does not require that an implemented interface be as accessible as the class implementing it!
using System;
public static class Outer
{
private interface IPrivates
{
string Name { set; }
}
public readonly static Inner TheInner = new Inner();
private readonly static IPrivates TheInnerPrivates = TheInner;
public class Inner : IPrivates
{
public string Name { get; private set; }
string IPrivates.Name { set { this.Name = value; } }
}
public static void DoIt()
{
TheInnerPrivates.Name = "abc";
}
}
public class Program
{
public static void Main()
{
Outer.DoIt();
Console.WriteLine(Outer.TheInner.Name);
}
}
Code inside of Outer may access the private members of Inner via the interface. Code outside of Outer cannot see anything other than the public members of Inner, because the interface they need to see the private members is itself private.
I voted for Eric's answer but wanted to put this here as 'something to consider'.
public class Tester
{
public Tester()
{
AppConfig.LogSettings.FileSize = 5; // compile error
Console.WriteLine(AppConfig.LogSettings.FileSize); // works
}
}
public static class AppConfig
{
// just an example of setting the value in the outer class
private static void SetFileSize(int size)
{
fileSize = size; // internal only setting works
}
private static int fileSize; // a member of AppConfig still
public static class LogSettings
{
public static int FileSize
{
get { return fileSize; } // internal classes can access private members of the outer class
}
}
}
When you access AppConfig externally you get the grouping you desire, however inside the AppConfig class the 'grouping' is simply about publicly exposing the getter, the actual member variable still belongs to AppConfig.
This works because the internal class can access private members of the outer class.
So if your grouping goal is mostly about the public interface - how you get the values - this approach is simpler, but if your goal is also have the grouping internally too...then obviously it doesn't deliver.
One option is to use a constructor of nested class to initialize values. For example:
public static class AppConfig {
static AppConfig() {
Log = new LogSettings(1);
}
public class LogSettings {
public LogSettings(int fileSize) {
FileSize = fileSize;
}
public int FileSize { get; private set; }
}
public static LogSettings Log { get; private set; }
}
Then other classes can create instance of LogSettings still, but cannot modify your instance.
If this is the approach you want to go with, I see 2 options:
You extract all the logic surrounding loading and parsing of the config file into a separate project (library), than you can mark your setters internal and other libraries won't be able to access them anymore.
You can implement a more explicit property which doesn't allow to set a value twice like:
private int? _fileSize;
public int FileSize {
get { return _fileSize ?? 0; }
set {
if (_fileSize.HasValue) {
throw new InvalidOperationException("You can only set the value once");
}
_fileSize = value;
}
}
Another option, which I've often used, is to encapsulate the parsing of different parts of a configuration to the sub classes. You provide that information in the constructor and the class initializes itself. (just like Evk commented in the meanwhile)
I have this situation: I need class2(string) constructor to only be accessible from within the class1 methods and not from external classes:
public class class1
{
public void access()
{
//want to make class2(string) be accessible only from here
}
public class class2
{
public class2()
{
}
private class2(string p)
{
}
}
}
I'm trying to validate a user, the class2() create an empty instance of the user class while the class2(...) login the user. now I have class1 login method access that can be called from my pages, and i dont want that any of my pages directly calls my class2(...) login but must all pass from class1.access() that returns the class2 with user informations.
edit: the purpose of this is to create a safe login procedure, I do not want to expose my login and make it accessible directly from my pages, I want that my pages pass from the logic of class1.access() which will make considerations on how/if to login a user and return and empty class2 if the login fail with also class2.valid=false; or will return a class2 with all the informations from the user. I need to access and create and empty class2 from my pages since I pass it as out param in my class1.access(login_credentials credentials, out class2 user_data)
As far as I know, there's no direct mechanism to restrict access to a nested class's constructor to its wrapping class only. There are a couple of code redesign workarounds though that you could consider. If you're willing, you can make the constructor internal:
public class class1
{
public void access()
{
var c = new class2("asdf");
}
public class class2
{
public class2()
{
}
internal class2(string p)
{
}
}
}
This will restrict access to that constructor to the assembly that class2 resides. If all you want to do is restrict access for third parties consuming your libraries, then that might be a viable solution.
Another option is you can take advantage of the fact that the nested class2 can access private members of class1. In this way you can promote a factory method to "expose" the constructor:
public class class1
{
private static Func<string, class2> CreateNewClass2;
static class1()
{
//this just forces the static constructor on `class2` to run.
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(class2).TypeHandle);
}
public void access()
{
class2 c = CreateNewClass2("asdf");
}
public class class2
{
static class2()
{
//this is where we create a delegate exposing/promoting our private constructor
class1.CreateNewClass2 = p => new class2(p);
}
public class2()
{
}
private class2(string p)
{
}
}
}
Honestly, this is a bit obtuse, but it will enforce the rules ultimately making it so that class1 and class2 are the only types that can ever access the class2(string p) constructor. I think your best bet though is to consider a possible change of your code design.
I would use an interface in this instance. After all an interface is exactly what you are describing.
DotNetFiddle.net Example
using System;
public class Program
{
// Properties you want others to have access too
public interface ICredentialsValidator
{
bool IsTest(string userName);
}
public static void Main()
{
var b = new PublicClass().GetCredentialsValidator();
Console.WriteLine(b.IsTest("test"));
Console.WriteLine(b.IsTest("blah"));
}
public class PublicClass
{
public ICredentialsValidator GetCredentialsValidator()
{
return new PrivateClass();
}
private class PrivateClass : ICredentialsValidator
{
public bool IsTest (string userName)
{
return userName == "test";
}
}
}
}
results:
True
False
You can pass your ICredentialsValidator around but nobody can create an ICredentialsValidator nor a class2. Simple OOP.
Although I find this to be very convoluted and overly complex. I would just use the singleton pattern and an interface for Liskov's Substitution Principle:
public interface ISecurity
{
bool IsTest(string userName);
}
public sealed class Security : ISecurity
{
private static readonly Lazy<Security> lazy =
new Lazy<Security>(() => new Security());
public static ISecurity Security Instance { get { return lazy.Value; } }
private Singleton()
{
}
public bool IsTest(string userName)
{
}
}
Then anyone would just
Security.Instance.IsTest("test");
You can't do it with normal constructs (use of access modifiers), but one way you can do it is with reflection:
public class Outer
{
public Inner GetInstanceOfInner(string s)
{
var innerInstance =
typeof(Inner).GetConstructor(
System.Reflection.BindingFlags.NonPublic, //Search for private/protected
null, //Use the default binder
new[] { typeof(string) }, //Parameter types in the ctor
null) //Default binder ignores this parameter
.Invoke(new[] { s }) as Inner; //Create and cast
return innerInstance;
}
public class Inner
{
public Inner() { }
private Inner(string s) { }
}
}
With reflection, you could invoke private or protected constructors using the BindingFlags.NonPublic to find the appropriate constructor. After that you .Invoke it to obtain a reference to the object and cast it for strong typing.
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.
Even though all common sense says no, I still am asking this question just to get a second opinion and become sure.
If I have a class hierarchy like so:
public class IntermediateObjectContext : System.Data.Objects.ObjectContext
{
public static Action<string> PrintHello { get; set; }
}
public class MyDatabaseContext : IntermediateObjectContext
{
public ObjectSet<Foo> Foos
{
get { // ... }
}
}
Then from a third, unrelated to Entity Framework object, if I access the static member of the IntermediateObjectContext class, in this case, if I subscribe to the delegate of the class, will that somehow instantiate a new ObjectContext?
class SomeClass
{
public void SomeMethod()
{
IntermediateObjectContext.PrintHello += SayHello;
}
public void SayHello(string s)
{
Debug.Print(s);
}
}
All reason says no, common sense says it won't, but I just want to make sure. I am trying to track down a memory hogger object.
What happens if
What happens to the memory situation if I have a static collection for SomeClass types like so:
public class SomeClassCollection
{
private static Collection<SomeClass> _col =
new Collection<SomeClass>();
public void Add(SomeClass c) { _col.Add(c); }
public void Remove(SomeClass c) { _col.Remove(c); }
}
And then some code adds SomeClass instances to SomeClassCollection like so:
public SomeClassCollectionConfig
{
public static RegisterSomeClasses()
{
SomeClassCollection.Add(new SomeClass());
SomeClassCollection.Add(new DerivesClassOfSomeClass());
}
}
(1) No, it won't instantiate an object.
(2) What happens if:
There it will allocate the empty collection col the first time any member of SomeClassCollection is accessed.
From the code, that's all it will do. You aren't using _col anywhere in the code presented.
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);
}
}
}
}