I have a project where I need to construct a fair amount of configuration data before I can execute a process. During the configuration stage, it's very convenient to have the data as mutable. However, once configuration has been completed, I'd like to pass an immutable view of that data to the functional process, as that process will rely on configuration immutability for many of its computations (for instance, the ability to pre-compute things based on initial configuration.) I've come up with a possible solution using interfaces to expose a read-only view, but I'd like to know if anybody has encountered problems with this type of approach or if there are other recommendations for how to solve this problem.
One example of the pattern I'm currently using:
public interface IConfiguration
{
string Version { get; }
string VersionTag { get; }
IEnumerable<IDeviceDescriptor> Devices { get; }
IEnumerable<ICommandDescriptor> Commands { get; }
}
[DataContract]
public sealed class Configuration : IConfiguration
{
[DataMember]
public string Version { get; set; }
[DataMember]
public string VersionTag { get; set; }
[DataMember]
public List<DeviceDescriptor> Devices { get; private set; }
[DataMember]
public List<CommandDescriptor> Commands { get; private set; }
IEnumerable<IDeviceDescriptor> IConfiguration.Devices
{
get { return Devices.Cast<IDeviceDescriptor>(); }
}
IEnumerable<ICommandDescriptor> IConfiguration.Commands
{
get { return Commands.Cast<ICommandDescriptor>(); }
}
public Configuration()
{
Devices = new List<DeviceDescriptor>();
Commands = new List<CommandDescriptor>();
}
}
EDIT
Based on input from Mr. Lippert and cdhowie, I put together the following (removed some properties to simplify):
[DataContract]
public sealed class Configuration
{
private const string InstanceFrozen = "Instance is frozen";
private Data _data = new Data();
private bool _frozen;
[DataMember]
public string Version
{
get { return _data.Version; }
set
{
if (_frozen) throw new InvalidOperationException(InstanceFrozen);
_data.Version = value;
}
}
[DataMember]
public IList<DeviceDescriptor> Devices
{
get { return _data.Devices; }
private set { _data.Devices.AddRange(value); }
}
public IConfiguration Freeze()
{
if (!_frozen)
{
_frozen = true;
_data.Devices.Freeze();
foreach (var device in _data.Devices)
device.Freeze();
}
return _data;
}
[OnDeserializing]
private void OnDeserializing(StreamingContext context)
{
_data = new Data();
}
private sealed class Data : IConfiguration
{
private readonly FreezableList<DeviceDescriptor> _devices = new FreezableList<DeviceDescriptor>();
public string Version { get; set; }
public FreezableList<DeviceDescriptor> Devices
{
get { return _devices; }
}
IEnumerable<IDeviceDescriptor> IConfiguration.Devices
{
get { return _devices.Select(d => d.Freeze()); }
}
}
}
FreezableList<T> is, as you would expect, a freezable implementation of IList<T>. This gains insulation benefits, at the cost of some additional complexity.
The approach you describe works great if the "client" (the consumer of the interface) and the "server" (the provider of the class) have a mutual agreement that:
the client will be polite and not try to take advantage of the implementation details of the server
the server will be polite and not mutate the object after the client has a reference to it.
If you do not have a good working relationship between the people writing the client and the people writing the server then things go pear-shaped quickly. A rude client can of course "cast away" the immutability by casting to the public Configuration type. A rude server can hand out an immutable view and then mutate the object when the client least expects it.
A nice approach is to prevent the client from ever seeing the mutable type:
public interface IReadOnly { ... }
public abstract class Frobber : IReadOnly
{
private Frobber() {}
public class sealed FrobBuilder
{
private bool valid = true;
private RealFrobber real = new RealFrobber();
public void Mutate(...) { if (!valid) throw ... }
public IReadOnly Complete { valid = false; return real; }
}
private sealed class RealFrobber : Frobber { ... }
}
Now if you want to create and mutate a Frobber, you can make a Frobber.FrobBuilder. When you're done your mutations, you call Complete and get a read-only interface. (And then the builder becomes invalid.) Since all the mutability implementation details are hidden in a private nested class, you can't "cast away" the IReadOnly interface to RealFrobber, only to Frobber, which has no public methods!
Nor can the hostile client create their own Frobber, because Frobber is abstract and has a private constructor. The only way to make a Frobber is via the builder.
This will work, but "malicious" methods may try to cast an IConfiguration to a Configuration and thereby bypass your interface-imposed restrictions. If you're not worried about that then your approach will work fine.
I usually do something like this:
public class Foo {
private bool frozen = false;
private string something;
public string Something {
get { return something; }
set {
if (frozen)
throw new InvalidOperationException("Object is frozen.");
// validate value
something = value;
}
}
public void Freeze() {
frozen = true;
}
}
Alternatively, you could deep-clone your mutable classes into immutable classes.
Why can't you provide a separate immutable view of the object?
public class ImmutableConfiguration {
private Configuration _config;
public ImmutableConfiguration(Configuration config) { _config = config; }
public string Version { get { return _config.Version; } }
}
or if you don't like the extra typing, make the set members internal rather than public - accessible within the assembly but not by clients of it?
I'm regularly working with a large, COM-based framework (ESRI's ArcGIS Engine) that handles modifications very similarly in some situations: there are the "default" IFoo interfaces for read-only access, and IFooEdit interfaces (where applicable) for modifications.
That framework is fairly well-known, and I'm not aware of any widespread complaints about this particular design decision behind it.
Finally, I think it's definitely worth some additional thought in deciding which "perspective" gets to be the default one: the read-only perspective or the full-access one. I would personally make the read-only view the default.
How about:
struct Readonly<T>
{
private T _value;
private bool _hasValue;
public T Value
{
get
{
if (!_hasValue)
throw new InvalidOperationException();
return _value;
}
set
{
if (_hasValue)
throw new InvalidOperationException();
_value = value;
}
}
}
[DataContract]
public sealed class Configuration
{
private Readonly<string> _version;
[DataMember]
public string Version
{
get { return _version.Value; }
set { _version.Value = value; }
}
}
I called it Readonly but I'm not sure that's the best name for it though.
Related
I'm reading some code, can you please explain what the below line does?
bool isFeatureEnabled = FeatureControl.Current.Features.AppDesigner.IsEnabled(organizationId,currentOrgDBVersion);
Here's the definitions of the above code
public sealed class FeatureControl : IFeatureControl
{
public static IFeatureControl Current { get; }
[XmlIgnore]
public IFeatureDetailContainer Features { get; set; }
....
}
public interface IFeatureControl
{
IFeatureDetailContainer Features { get; set; }
...
}
public interface IFeatureDetailContainer
{
IFeatureDetail AppDesigner { get; }
}
public interface IFeatureDetail
{
bool IsEnabled(Guid organizationId, Version currentOrgDBVersion);
}
I don't see any instances created, how does this work?
Sorry, I copied metadata, I just found the actual code:
public sealed class FeatureControl : IFeatureControl
{
private static readonly Lazy<IFeatureControl> current = new Lazy<IFeatureControl>(() => new FeatureControl());
private IFeatureDetailContainer features;
public static IFeatureControl Current
{
get
{
return current.Value;
}
}
/// <summary>
/// Accessor to the Features List for Developers to retrieve the information
/// </summary>
[XmlIgnore]
public IFeatureDetailContainer Features
{
get
{
return this.features;
}
set
{
this.features = value;
}
}
}
It is a singleton pattern. Normally, the instance is created inside constructor.
public interface IFeatureControl { }
public sealed class FeatureControl : IFeatureControl
{
public static IFeatureControl Current { get; }
static FeatureControl()
{
if (Current == null)
{
Current = new FeatureControl();
}
}
}
[TestFixture]
public class FeatureControlTests
{
[Test]
public void IsFeatureControlSingleton()
{
IFeatureControl c1 = FeatureControl.Current;
IFeatureControl c2 = FeatureControl.Current;
Assert.AreSame(c1, c2);
}
}
At some point in the code (not shown here) you can expect the object IFeatureControl::Current is being created / new'd.
Your line of code is merely accessing that value. Note that if you run the code without actually instantiating the Current object you'll get a null ref. error.
You can program an elaborate set of code using Interfaces and the code will compile and look great, however if none of the interface objects are instantiated with new'd instances of classes that inherit from the Interface you'll get null reference exceptions.
Consider the use of interfaces in this example an outline for how things WILL be arranged and how they WILL operate. However it's just an outline and you'll need to colour inside the lines to actually achieve an outcome.
Good luck!
I am familiar with these patterns but still don't know how to handle following situation:
public class CarFactory
{
public CarFactory(Dep1,Dep2,Dep3,Dep4,Dep5,Dep6)
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(Dep1,Dep2,Dep3);
break;
case B:
return new Car2(Dep4,Dep5,Dep6);
break;
}
}
}
In general the problem is with amount of references that needs to be injected. It will be even worse when there are more cars.
First approach that comes to my mind is to inject Car1 and Car2 in factory constructor but it is against factory approach because factory will return always the same object. The second approach is to inject servicelocator but it's antipattern everywhere. How to solve it?
Edit:
Alternative way 1:
public class CarFactory
{
public CarFactory(IContainer container)
{
_container = container;
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return _container.Resolve<ICar1>();
break;
case B:
return _container.Resolve<ICar2>();
break;
}
}
}
Alternative way 2 (too hard to use because of too many of dependencies in tree):
public class CarFactory
{
public CarFactory()
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(new Dep1(),new Dep2(new Dep683(),new Dep684()),....)
break;
case B:
return new Car2(new Dep4(),new Dep5(new Dep777(),new Dep684()),....)
break;
}
}
}
Having a switch case statement inside of a factory is a code smell. Interestingly, you don't seem to be focusing on solving that issue at all.
The best, most DI friendly solution for this scenario is the strategy pattern. It allows your DI container to inject the dependencies into the factory instances where they belong, without cluttering up other classes with those dependencies or resorting to a service locator.
Interfaces
public interface ICarFactory
{
ICar CreateCar();
bool AppliesTo(Type type);
}
public interface ICarStrategy
{
ICar CreateCar(Type type);
}
Factories
public class Car1Factory : ICarFactory
{
private readonly IDep1 dep1;
private readonly IDep2 dep2;
private readonly IDep3 dep3;
public Car1Factory(IDep1 dep1, IDep2 dep2, IDep3 dep3)
{
this.dep1 = dep1 ?? throw new ArgumentNullException(nameof(dep1));
this.dep2 = dep2 ?? throw new ArgumentNullException(nameof(dep2));
this.dep3 = dep3 ?? throw new ArgumentNullException(nameof(dep3));
}
public ICar CreateCar()
{
return new Car1(this.dep1, this.dep2, this.dep3);
}
public bool AppliesTo(Type type)
{
return typeof(Car1).Equals(type);
}
}
public class Car2Factory : ICarFactory
{
private readonly IDep4 dep4;
private readonly IDep5 dep5;
private readonly IDep6 dep6;
public Car2Factory(IDep4 dep4, IDep5 dep5, IDep6 dep6)
{
this.dep4 = dep4 ?? throw new ArgumentNullException(nameof(dep4));
this.dep5 = dep5 ?? throw new ArgumentNullException(nameof(dep5));
this.dep6 = dep6 ?? throw new ArgumentNullException(nameof(dep6));
}
public ICar CreateCar()
{
return new Car2(this.dep4, this.dep5, this.dep6);
}
public bool AppliesTo(Type type)
{
return typeof(Car2).Equals(type);
}
}
Strategy
public class CarStrategy : ICarStrategy
{
private readonly ICarFactory[] carFactories;
public CarStrategy(ICarFactory[] carFactories)
{
this.carFactories = carFactories ?? throw new ArgumentNullException(nameof(carFactories));
}
public ICar CreateCar(Type type)
{
var carFactory = this.carFactories
.FirstOrDefault(factory => factory.AppliesTo(type));
if (carFactory == null)
{
throw new InvalidOperationException($"{type} not registered");
}
return carFactory.CreateCar();
}
}
Usage
// I am showing this in code, but you would normally
// do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6)
});
// And then once it is injected, you would simply do this.
// Note that you could use a magic string or some other
// data type as the parameter if you prefer.
var car1 = strategy.CreateCar(typeof(Car1));
var car2 = strategy.CreateCar(typeof(Car2));
Note that because there is no switch case statement, you can add additional factories to the strategy without changing the design, and each of those factories can have their own dependencies that are injected by the DI container.
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6),
new Car3Factory(dep7, dep8, dep9)
});
var car1 = strategy.CreateCar(typeof(Car1));
var car2 = strategy.CreateCar(typeof(Car2));
var car3 = strategy.CreateCar(typeof(Car3));
Answering your comment about code example with Composition Root.
You can create following and this is not a Service Locator.
public class CarFactory
{
private readonly Func<Type, ICar> carFactory;
public CarFactory(Func<Type, ICar> carFactory)
{
this.carFactory = carFactory;
}
public ICar CreateCar(Type carType)
{
return carFactory(carType);
}
and this is how look your Composition Root using Unity DI container :
Func<Type, ICar> carFactoryFunc = type => (ICar)container.Resolve(type);
container.RegisterInstance<CarFactory>(new CarFactory(carFactoryFunc));
I answered a similar question some time ago. Basically it's all about your choice. You have to choose between verbosity (which gives you more help from a compiler) and automation, which allows you to write less code but is more prone to bugs.
This is my answer supporting verbosity.
And this is also a good answer that supports automation.
EDIT
I believe the approach you consider wrong is actually the best. Truth being said, usually there won't so many dependencies in there. I like this approach because it's very explicit and rarely results in runtime errors.
Alternative way 1:
This one is bad. It's actually a service locator, which is considered an anti-pattern.
Alternative way 2
Like you wrote, it's not easy to use if mixed with IOC containter. However in some case a similar approach (poor man's DI) can be useful.
All in all, I wouldn't bother having "many" dependencies in your factories. It's a simple, declarative code. It takes seconds to write and can save you hours of struggling with runtime errors.
I would consider giving the dependencies a good structure so you can utilize something similar to Wiktor's answer, but I would abstract the Car factory itself. Then, you don't use the if..then structure.
public interface ICar
{
string Make { get; set; }
string ModelNumber { get; set; }
IBody Body { get; set; }
//IEngine Engine { get; set; }
//More aspects...etc.
}
public interface IBody
{
//IDoor DoorA { get; set; }
//IDoor DoorB { get; set; }
//etc
}
//Group the various specs
public interface IBodySpecs
{
//int NumberOfDoors { get; set; }
//int NumberOfWindows { get; set; }
//string Color { get; set; }
}
public interface ICarSpecs
{
IBodySpecs BodySpecs { get; set; }
//IEngineSpecs EngineSpecs { get; set; }
//etc.
}
public interface ICarFactory<TCar, TCarSpecs>
where TCar : ICar
where TCarSpecs : ICarSpecs
{
//Async cause everything non-trivial should be IMHO!
Task<TCar> CreateCar(TCarSpecs carSpecs);
//Instead of having dependencies ctor-injected or method-injected
//Now, you aren't dealing with complex overloads
IService1 Service1 { get; set; }
IBuilder1 Builder1 { get; set; }
}
public class BaseCar : ICar
{
public string Make { get; set; }
public string ModelNumber { get; set; }
public IBody Body { get; set; }
//public IEngine Engine { get; set; }
}
public class Van : BaseCar
{
public string VanStyle { get; set; }
//etc.
}
public interface IVanSpecs : ICarSpecs
{
string VanStyle { get; set; }
}
public class VanFactory : ICarFactory<Van, IVanSpecs>
{
//Since you are talking of such a huge number of dependencies,
//it may behoove you to properly categorize if they are car or
//car factory dependencies
//These are injected in the factory itself
public IBuilder1 Builder1 { get; set; }
public IService1 Service1 { get; set; }
public async Task<Van> CreateCar(IVanSpecs carSpecs)
{
var van = new Van()
{
//create the actual implementation here.
};
//await something or other
return van;
}
}
I didn't list it, but you can implement multiple types of cars and their corresponding factories now and use DI to inject whatever you need.
First, you have a concrete factory, an IoC container could be an alternative rather than something to help you there.
Then, just refactor the factory to not to expect a full possible parameter list in the factory constructor. This is the primary issue - why are you passing so many parameters if the factory method doesn't need them?
I would rather pass specific parameters to the factory method
public abstract class CarFactoryParams { }
public class Car1FactoryParams : CarFactoryParams
{
public Car1FactoryParams(Dep1, Dep2, Dep3)
{
this.Dep1 = Dep1;
...
}
public class Car2FactoryParams
...
public class CarFactory
{
public ICar CreateCar( CarFactoryParams params )
{
if ( params is Car1FactoryParams )
{
var cp = (Car1FactoryParams)params;
return new Car1( cp.Dep1, cp.Dep2, ... );
}
...
if ( params is ...
By encapsulating the parameter list in a specific class you just make the client provide exactly these parameters that are required for specific factory method invocation.
Edit:
Unfortunately, it was not clear from your post what are these Dep1, ... and how you use them.
I suggest following approach then that separates the factory provider from actual factory implementation. This approach is known as the Local Factory pattern:
public class CarFactory
{
private static Func<type, ICar> _provider;
public static void SetProvider( Func<type, ICar> provider )
{
_provider = provider;
}
public ICar CreateCar(type)
{
return _provider( type );
}
}
The factory itself doesn't have any implementation, it is here to set the foundation to your domain API, where you want your car instances to be created with this API only.
Then, in the Composition Root (somewhere near the starting point of the app where you configure your actual container), you configure the provider:
CarFactory.SetProvider(
type =>
{
switch ( type )
{
case A:
return _container.Resolve<ICar1>();
case B:
return _container.Resolve<ICar2>();
..
}
);
Note that this example implementation of the factory's provider uses a delegate but an interface could also be used as a specification for an actual provider.
This implementation is basically #1 from your edited question, however, it doesn't have any particular downsides. The client still calls:
var car = new CarFactory().CreareCar( type );
Many DI containers support the notion of named dependencies.
E.g. (Structuremap syntax)
For<ICar>().Use<CarA>().Named("aCar");
Container.GetNamedInstance("aCar") // gives you a CarA instance
If you use something like a convention, a rule how the name is derived from the concrete car type itself, you have a situation where you don't need to touch the factory anymore when you extend the system.
Using this in a factory is straightforward.
class Factory(IContainer c) {
public ICar GetCar(string name) {
Return c.GetNamedInstance(name);
}
}
I wanted to know what is a good option to solve this issue ,
I have a class that expose an enum : (this is just an example)
public class Foo
{
public State FooState { get; private set; }
public string SomeData { get; set; }
public Foo(State state)
{
FooState = state;
}
public Foo()
{
}
public enum State
{
None,
Bad,
Good
}
}
in one use of the class the user can adjust the state, and on the other he can't so the state is set on NONE and that good but i dont want the user to have the possibility of setting it to None. i Know that there isnt an internal enum field obviously, is there any way it can be done else, bare in mine that the Foo class cant be changed due to specification.
Clarification
The meaning of the class can not be change is that the design and purpose of the class can not change, not the class itself.
The state of the class is only in use when the c'tor get a value. i cant use two classes or use interface due to reflection use in the future. (i just cant use typeof)
I believe you can do this by providing two interfaces with different access level, implement them explicitly and instead of Foo type use one of the interfaces either for read-only or full access.
Since Foo can not be changed you can use Wrapper approach:
Foo foo = new Foo(State.Good);
FooWrapper fooWrapper = new FooWrapper(foo);
// would be read-write
(FooWrapper as IReaonlyState).State
// would be readonly
(FooWrapper as IWritableState).State
public interface IReadonlyState
{
State FooState { get; }
}
public interface IWritableState
{
State FooState { get; set; }
}
public class FooWrapper : IReadonlyState, IWritableState
{
Foo foo;
public FooWrapper(Foo foo)
{
this.foo = foo;
}
State IReadonlyState.FooState
{
get
{
return this.foo.FooState;
}
}
State IWritableState.FooState
{
get
{
return this.foo.FooState;
}
set
{
this.foo.FooState = value;
}
}
}
So, you want the consumer to be able to set both State=Bad and State=Good.
But if State==None you should be able to read, but not change it. Sounds like you need to implement the setter explicitly.
I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:
public interface ISomeType<V>
{
V Value {get; set;}
}
public interface ISomeTypeWrapper
{
object Value { get; set; }
}
public class SomeTypeWrapper<T> : ISomeTypeWrapper
where T : ISomeType<???>
{
T someType;
public SomeTypeWrapper(T wrappedSomeType)
{
someType = wrappedSomeType
}
public object Value
{
get { return someType.Value; }
set { someType.Value = value != null ? value : default(T); }
}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.
I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.
How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)
How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?
You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.
container
.Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
.Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());
You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.
Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:
public class SomeTypeWrapperFactory
{
public ISomeType<int> CreateWrapper(SomeType1 someType1)
{
return new SomeType1Wrapper(someType1);
}
public ISomeType<string> CreateWrapper(SomeType2 someType2)
{
return new SomeType2Wrapper(someType2);
}
}
public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }
Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.
Why SomeTypeWrapper but not SomeObjectWrapper?
public class SomeObjectWrapper : ISomeType
{
Object _someObject;
PropertyInfo _valuePropertyInfo;
public SomeObjectWrapper(Object wrappedSomeObject)
{
_someObject = wrappedSomeObject;
_valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
}
public object Value
{
get { return _valuePropertyInfo.GetValue(_someObject, null); }
set { _valuePropertyInfo.SetValue(_someObject, value, null); }
}
}
Edited With .NET 3.5 using LinFu
You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution.
In that case I would personally choose Orsol's solution.
However: here's an example with LinFu's ducktyping.
public interface ISomeType {
object Value{get; set;}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeWrapperFactory
{
public static ISomeType CreateSomeTypeWrapper(object aSomeType)
{
return aSomeType.CreateDuck<ISomeType>();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
foreach(var o in someTypes)
{
Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
}
Console.ReadLine();
}
}
Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).
With .NET 4 using dynamic
See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern.
In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeVisitor
{
public void VisitAll(object[] someTypes)
{
foreach(var o in someTypes) {
// this should be in a try-catch block
Console.WriteLine(((dynamic) o).Value);
}
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
var vis = new SomeTypeVisitor();
vis.VisitAll(someTypes);
}
}
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 .