My project has many handler classes that derive from a common base class, and I am trying to get each of the handler classes to install themselves in a static table in the base class, and my first thought was a static constructor.
But this seems to use a super-lazy evaluation, and since I never refer to the derived classes directly (always by the handler table), this never triggers the static ctor.
Super simple stupid example:
public abstract class BlahBase
{
public static readonly Dictionary<string, BlahBase> Handlers = new();
public static BlahBase FindHandler(string name)
{
// look up in the Handlers table, return to caller
}
// other stuff
}
public class BlahFooHandler : BlahBase
{
static BlahFooHandler()
{
Handlers.Add("foo", typeof(BlahFooHandler));
}
// other stuff
}
public class BlahBarHandler : BlahBase
{
static BlahBarHandler()
{
Handlers.Add("bar", typeof(BlahBarHandler));
}
// other stuff
}
The idea is that BlahFooHandler and BlahBarHandler's static constructors would install themselves in the base Handlers table, and none of this apparently works without directly touching the derived class to trigger the static constructor. I'm trying to make this entirely dynamic.
I've spent much time looking into static constructors, and most questions revolve around lazy behavior: I want non lazy behavior.
An alternate approach is to use reflection and/or an [Attribute] on each of the handler classes, both of which I'm comfortable doing, but wonder if I'm missing an obvious language facility to achieve this.
You should create a static class with a static constructor and remove the other static constructors then in one spot add the handlers
public static class BlahHelper
{
public static readonly Dictionary<string, BlahBase> Handlers = new();
static BlahHelper
{
Handlers.Add("foo", typeof(BlahFooHandler));
Handlers.Add("bar", typeof(BlahBarHandler));
}
public static BlahBase FindHandler(string name)
{
// look up in the Handlers table, return to caller
}
// other stuff
}
public abstract class BlahBase
{
// other stuff
}
public class BlahFooHandler : BlahBase
{
// other stuff
}
public class BlahBarHandler : BlahBase
{
// other stuff
}
The first thing I did was change your code so it would compile; you declare Handlers to be a Dictionary<string, BlahBase>, but you have code like:
Handlers.Add("foo", typeof(BlahFooHandler));
Which adds Types to the dictionary, not BlahBase instances.
So, BlahBase now looks like:
public abstract class BlahBase
{
public static readonly Dictionary<string, Type> Handlers = new Dictionary<string, Type>();
public static BlahBase FindHandler(string name)
{
if (Handlers.TryGetValue(name, out var type))
{
var result = Activator.CreateInstance(type);
return result as BlahBase;
}
return null;
}
// other stuff
}
The rest of your code stays the same.
The rule for static constructors is that they get invoked some time before the first time the type is used. So, what I did is this:
BlahFooHandler unused1 = new BlahFooHandler();
BlahBarHandler unused2 = new BlahBarHandler();
var blah = BlahBase.FindHandler("BlahFooHandler");
I create a dummy instance of each of my BlahBase subclasses somewhere before I call BlahBase.FindHandler. Each of those statements fires of the appropriate static constructore. Then, you away to the races.
For what it's worth, I tried just declaring references to instances of those types:
BlahFooHandler unused1;
BlahBarHandler unused2;
It didn't invoke the static constructors.
Related
I wanted to use a static constructor in derived classes to register object constructor lambdas for those classes to be called when passing a certain Type object.
Since a static constructor is only called just before the first object of that class is created BUT I want to use the result of the static constructor to determine what kind of object to create, this mechanism fails, the constructor lambda is not found.
Is there any way out of this?
public abstract class Cacheable
{
// ... details do not matter ...
}
public class Series: Cacheable
{
// ... details do not matter ...
}
public abstract class CacheableViewForm
{
static Dictionary<Type, Func<CacheableViewForm>> cacheableViewFormConstructors = new Dictionary<Type, Func<CacheableViewForm>>();
protected static void Register<CacheableViewFormClass, CacheableClass>()
where CacheableViewFormClass: CacheableViewForm, new()
where CacheableClass: Cacheable
{
cacheableViewFormConstructors[typeof(CacheableClass)] = (() => new CacheableViewFormClass());
}
public static CacheableViewForm CreateFromTargetType(Type cacheableType)
{
return cacheableViewFormConstructors[cacheableType]();
}
// ... details do not matter ...
}
public class SeriesViewForm: CacheableViewForm
{
static SeriesViewForm() {Register<SeriesViewForm, Series>();}
// ... details do not matter ...
}
// fails because CacheableViewForm.Register<> has not been executed yet!
CacheableViewForm newForm = CacheableViewForm.CreateFromTargetType(typeof(Series));
My solution is to move initialization (from the static constructor of the derived classes) to the static constructor of the base class (which gets called automatically before executing my first call to the CreateFromTargetType method) and using reflection in there to examine the derived classes. In the derived classes I defined static methods (TargetType) which return the specific Type they are operating on.
Neither elegant nor compact, and certainly not super fast, but it allows me to keep the association between derived class (e.g. SeriesViewForm) and the data type it operates on (typeof(Series)) close together (in the same class definition).
public abstract class CacheableViewForm: Form
{
static Dictionary<Type, Func<CacheableViewForm>> CacheableViewFormConstructors = new Dictionary<Type, Func<CacheableViewForm>>();
static CacheableViewForm()
{
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach(Assembly assembly in allAssemblies)
{
Type[] cacheableViewFormTypes = assembly.GetExportedTypes().Where(t => typeof(CacheableViewForm).IsAssignableFrom(t) && t != typeof(CacheableViewForm)).ToArray();
foreach (Type cacheableViewFormType in cacheableViewFormTypes)
{
MethodInfo mi = cacheableViewFormType.GetMethod("TargetType");
Type cacheableType = (Type)mi.Invoke(null, null);
Func<CacheableViewForm> ctorDelegate = (() => (CacheableViewForm)(Activator.CreateInstance(cacheableViewFormType)));
CacheableViewFormConstructors[cacheableType] = ctorDelegate;
}
}
}
public static CacheableViewForm CreateFromTargetType(Type cacheableType)
{
return CacheableViewFormConstructors[cacheableType]();
}
}
public class SeriesViewForm: CacheableViewForm
{
public static Type TargetType() {return typeof(Series);}
// ...
}
Say I have a generic class Foo, that has a variable that is protected
public class Foo<T>
{
protected bool knowsFu;
}
I also have 2 sub-classes: Bar and Pipe
public class Bar : Foo<Bar> {}
public class Pipe : Foo<Pipe> {}
It is actually possible for me to access the knowsFu in Pipe FROM Bar, e.g.:
public class Bar : Foo<Bar>
{
void UpdateFuInOtherClass(Pipe p)
{
p.knowsFu = false;
}
}
Is this intended behaviour? (If so, what would be the usecase?)
Is there a way for me to prevent other Foo-Subclasses from modifying/reaching the protected variable inside of my current subclass?
More specifically: I'm using a generic class to implement the Singleton-Pattern:
https://en.wikipedia.org/wiki/Singleton_pattern
However, I'm currently able to access any singleton's protected instance-variable, as long as I am inside of another Singleton. Is there a way to prevent this?
EDIT: It might be relevant to note that the protected variable (knowsFu) is actually STATIC as well.
EDIT2: Ok, maybe the example was abit too generic.. here's how I'm actually currently implementing it:
why use Singleton? A:The platform I'm working on is Unity3D, in which the pattern is used frequently
I have a generically typed abstract class SingletonBehaviour
public abstract class SingletonBehaviour<T> where T : MonoBehaviour
{
public static T Instance { get { return instance; } }
protected static T instance { get; private set; } }
// Loading is done through Unitys Awake-Method
}
One of the Singleton-Objects that I'm using is the APIManager
public class APIManager : SingletonBehaviour<APIManager>
{
// Methods like SendHTTPPost(), HTTPGet(), etc.
}
However, since most of my projects need some better API-implementation than that, what I'm currently doing is:
public class ProjectAAPIManager : APIManager
{
// Overriding Instance so my return value is not APIManager but instead ProjectAAPIManager
public static new ProjectAAPIMamager Instance { get { return (ProjectAAPIManager)instance; } }
}
This ^ is the reason my (inner) instance-variable is protected, and not private.
However, because of this, any other SingletonBehaviour in my project can now access the (inner) instance-variable on my ProjectAAPIManager
public class GameController : SingletonBehaviour<GameController>
{
private void AMethod()
{
// Accessing inner variable instead of public one
ProjectAAPIManager.instance.DoSomething();
}
}
As it's only the getter, this currently does not really matter. But what if I'd need access to the setter in my subclass as well?
Also: would it be worth it to generically type my APIManager as well?
Your question is nothing short of bewildering. How can you make a protected member not be accesible from a derived class? Well, a good start is not making it protected.
protected is by definition exactly what you don't want, so don't use it! Use private instead.
If what you are asking is how to make it a readonly member when accessed from derived types, you have two options:
Declare it as readonly in the base class if possible.
Use a protected property instead with a private setter.
Many novice coders seems to think protected members aren't part of the public surface of the type but they really are, as long as the class can be extended. As such, the rules of public members apply: never expose public fields unless they are readonly or constants, use properties instead.
You should not have classes that implement your generic singleton class.
Otherwise, by default, your protected fields will be accessible by the subclasses (it's what "protected" keyword does)
Instead, you should do something like this:
class Program
{
static void Main(string[] args)
{
var barInstance = Foo<Bar>.GetInstance();
}
}
public class Foo<T> where T : new()
{
protected bool knowsFu;
private static T _instance;
public static T GetInstance()
{
if (_instance == null)
_instance = new T();
return _instance;
}
}
public class Bar
{
public Bar()
{
}
}
Edit 1:
To use a singleton, you should not make another class implement the singleton behavior (This is not how the singleton pattern works).
To use the same classes as your second example, you should do something like this.
public class SingletonBehaviour<T> where T : new()
{
public static T Instance
{
get
{
if(instance == null)
instance = new T()
return instance;
}
}
private static T instance { get; set; }
}
public class APIManager // This class should not inherit from the SingletonBehavior class
{
// Methods like SendHTTPPost(), HTTPGet(), etc.
}
public class ProjectAAPIManager : APIManager
{
public ProjectAAPIManager GetInstance() => SingletonBehavior<ProjectAAPIManager>.Instance();
}
I have a program that needs to be able to interface with multiple platforms ie read/write files, read/write database or read/write web requests. The platform interface is selected from configuration and does not change while the application is running. I have a single read/write interface class which is inherited by the platform specific classes so that this is abstracted from the rest of the program.
My problem is that I have 10 classes in my framework that will need to use this interface. Instead of making multiple instances of this class, or passing a single reference to every class, I figured it would make sense to make the interface static. Unfortunately I have just learned that Interfaces cannot have static methods, static methods cannot call non-static methods and static methods cannot be abstract.
Can anyone show me another method of approaching this situation?
Edit:
Thanks for everyone's input, here is my solution based on the example given by Patrick Hofman (thank you!)
interface TheInterface
{
void read();
void write();
}
public class X : TheInterface
{
public void read() { //do something }
public void write() { //do something }
}
public class Y : TheInterface
{
public void read() { //do something }
public void write() { //do something }
}
public class FileAccessor
{
public static TheInterface accessor;
public static TheInterface Accessor
{
get
{
if(accessor) return accessor;
}
}
}
This can be called by any class as:
static void Main(string[] args)
{
switch (Config.interface)
{
case "X":
FileAccessor.accessor = new Lazy<X>();
case "Y":
FileAccessor.accessor = new Lazy<Y>();
default:
throw new Lazy<Exception>("Unknown interface: " + Config.interface);
}
FileAccessor.Accessor.read();
}
Indeed, interfaces, or abstract classes can't be static themselves, but the further implementation can. Also, you can use the singleton pattern to make your life easier, and allow inheritance, etc.
public class X : ISomeInterface
{
private X() { }
public static X instance;
public static X Instance
{
get
{
return instance ?? (instance = new X());
}
}
}
Or, using Lazy<T>:
public class X : ISomeInterface
{
private X() { }
public static Lazy<X> instanceLazy = new Lazy<X>(() => new X());
public static X Instance
{
get
{
return instance.Value;
}
}
}
Disclaimer: I am the author of the library described below.
I don't know if this helps you, but I have written a library (very early version yet) that allows you to define static interfaces, by defining normal interfaces and decorating their methods with an attribute named [Static], for example:
public interface IYourInterface
{
[Static]
void DoTheThing();
}
(Note that you don't explicitly add this interface to your implementations.)
Once you have defined the interface, you can instantiate it from within your code with any valid implementation you choose:
return typeof(YourImplementation).ToStaticContract<IYourInterface>();
If the methods can't be found in YourImplementation, this call fails at runtime with an exception.
If the methods are found and this call is successful, then the client code can polymorphically call your static methods like this:
IYourInterface proxy = GetAnImplementation();
proxy.DoTheThing();
You can make a Static Class which has Variable of your Interface.
public static class StaticClass
{
public static ISomeInterface Interface;
}
Now you can access the Instance from everywhere in your Framwork
static void Main(string[] args)
{
StaticClass.Interface = new SomeClass();
}
I want to have a class like:
public class Forest<S, T>
{
static IList<Animal> coolGuys = new List<Animal>();
}
But I want coolGuys to be really static, which means it has to be unique through the entire lifetime of the application. And right now its not. MS discourages this pattern, ReSharper warns, but how does one really achieve what I want?
May be I will have to do more work by creating another static class and have a public static field there or a public instance field in another singleton class. Its ok to have a redundant public class to hold just a static field, but the thing I want to avoid is the field being public/internal. I mean coolGuys is just meant for Forest<,>, why expose the incoherent things to outside world.
public class Forest
{
public static IList<Animal> coolGuys = new List<Animal>(); //want to avoid
}
public class Forest<S, T>
{
Forest.coolGuys.Add(cutie);
}
Any better pattern?
Approach 1 - Inject a State Provider
Create a type to store data.
Abstract it with an interface, so you can inject a different provider if desired (e.g. for testing).
Consuming class doesn't care about the implementation, other than it guarantees statefulness.
Concurrent dictionary takes care of thread safety.
public interface IStateProvider
{
void Store( string key, object value );
object Get( string key );
}
public class StateProvider : IStateProvider
{
private static ConcurrentDictionary<string, object> _storage = new ConcurrentDictionary<string, object>();
public void Store( string key, object value )
{
// add to storage
}
public object Get( string key )
{
// get from storage
}
}
public class Forest<T1, T2>
{
private IStateProvider _stateProvider;
public Forest( IStateProvider stateProvider )
{
_stateProvider = stateProvider;
}
public void Foo()
{
// do something with the stateful value
}
}
// of course, you could do this with a DI framework
var stateProvider = new StateProvider();
var forest = new Forest<Foo, Bar>( stateProvider );
Approach 2 - Base Class
This approach is less elegant but a bit more straightforward.
public abstract class ForestBase
{
private static List<object> _staticList = new List<object>();
protected List<object> StaticList
{
get { return _staticList; }
}
}
public class Forest<T1, T2> : ForestBase
{
public void Foo()
{
StaticList.Add( 12345 );
}
}
This hides internal data and should give you only one single instance of the static list, versus one instance per combination of generic arguments.
Greetings!
I have a class which is used like a cache:
public sealed class MyCache<T> : IDisposable
{
private ReaderWriterLockSlim theLock = new ReaderWriterLockSlim();
private Dictionary<int, T> theCache = new Dictionary<int, T>();
public void Add(int key, T value)
{
// ... logic/code to add to the dictionary
}
public void Clear()
{
theLock.EnterWriteLock();
try
{
theCache.Clear();
}
finally
{
theLock.ExitWriteLock();
}
}
}
This cache is used many times, so there are often multiple instances of this at any given time.
Example 1:
public static class SpecialPageCache
{
public static MyCache<string> SpecialPage = new MyCache<string>();
}
Example 2:
public static class DdListCache
{
public static MyCache<List<int, string>> DdlList = new MyCache<List<int, string>>();
}
And so on.
I have a service that can clear the caches on-demand, but unfortunately, each one has to be cleared like so:
private void ClearThemAll()
{
SpecialPageCache.SpecialPage.Clear();
DdListCache.DdlList.Clear();
// repeat for all other caches that may exist ...
}
How can I use reflection (or something else?) to call each cache's Clear() method without having to explcitly do it for each one like I do in the above ClearThemAll() method?
Ick. You'd have to go through all the types in the assembly that you're interested in, and check all the static fields. This is made even more interesting because it's a generic type. Your life will be simpler if you have a nongeneric base class:
public abstract class MyCache : IDisposable
{
public abstract void Clear();
}
public sealed class MyCache<T> : MyCache
{
// ...
}
Then at least it's relatively easy to detect whether the type of a particular field is a MyCache, fetch its value and call Clear on it without messing around with reflection over generic types.
This is generally a nasty problem though - are you sure you want to clear all the caches like this, without really "understanding" which caches you're clearing?
public interface ICache : IDisposable
{
void Clear();
}
public interface ICache<T> : ICache
{
}
public abstract class CacheBase<T> : ICache<T>
{
}
public sealed class SpecialPageCache : CacheBase<string>
{
internal SpecialPageCache()
{
}
}
public static class CacheFactory
{
private static List<ICache> cacheList = new List<ICache>();
public static TCache Create<TCache>()
where TCache : ICache, new()
{
var result = new TCache();
cacheList.Add(result);
return result;
}
public static void ClearAll()
{
cacheList.ForEach((c) => c.Clear());
}
}
You could store references to all of your instanced caches in a list. Then iterate same list, and call Clear on each MyCache. =)
Reflection sounds nasty. Without knowing more about your object lifetime, would the following work?
public abstract class MyCacheBase : IDisposable {
public static List<MyCache> caches = new List<MyCache>();
public MyCacheBase() {
caches.Add(this); // Add all constructed caches to the list
}
public static void ClearAllCaches() {
foreach (MyCache cache in cache) // clear all constructed
cache.Clear(); // caches in the list.
}
public void Finalize() {
Dispose();
}
public void Dispose() {
caches.Remove(this); // Remove disposed classes from the list
}
public abstract void Clear();
}
public sealed class MyCache<T> : MyCacheBase
{
// Rest of the implementation
}
(Thanks to Jon for noting the genericity. Almost missed it.)
If you want to have something like user specific caches you could add a user specific CacheFactory which would keep track of the caches created through it and its ClearAll() method would only clear those caches.
Why do you need to specifcally clear them are they using resources which need to be released ?
I'm wondering if you couldnt use the System.WeakReference so that the cache is garbarge collected as and when ?
http://msdn.microsoft.com/en-us/library/system.weakreference.aspx
This sound really familiar to how Inversion of Control containers work. Why not just have something like a
Dictionary<Type, Dictionary<int, object>>
All of the functions would then take a type T and then use that type to look up the appopriate dictionary. One static MyCache could handle all your type and it could be disposed with one call.
If you really want to do reflection then you'd do something like this:
List<object> caches;
foreach (object obj in caches)
{
Type t = obj.GetType();
MethodInfo m = t.GetMethod("Clear");
// Object does not have a public instance method named "Clear"
if (m == null) { continue; }
m.Invoke(obj, new object[0]);
}