I constantly load objects from the database. Usually I would load the object when I need it, and in the constructor I call the database and populate all the methods I need to.
What I had done to speed up this process was create a task in the constructor and use wait before I returned the value in a getter. For example
Before:
class Foo{
public string Bar {get;set;}
public Foo(int id){
DataRow res;
//Do database operations
Bar = res["Bar"].ToString()
}
}
Now:
class Foo{
private Task LoadTask;
private string _Bar;
public string Bar {
get {
LoadTask.Wait();
return _Bar;
}
set {
_Bar = value;
}
}
public Foo(int id){
LoadTask = Task.Factory.StartNew(() => {
DataRow res;
//Do database operations
Bar = res["Bar"].ToString();
});
}
}
What I am wanting to do is extend a class, where in the constructor it fires off this task, calls an overridden method in the sub class and then block any getting of any property until the task completes.
The most I found was this, but not to sure if its what I want at all
http://www.gutgames.com/post/Overridding-a-Property-With-ReflectionEmit.aspx
As I said earlier, I think this design can be improved, but I appreciated the technical challenge so I gave it a shot.
What you talked about sounded not too dissimilar to Entity Framework's dynamically created change tracking proxies, so I had a quick look around for frameworks which work with dynamic proxies and quickly settled on Castle Project (http://www.nuget.org/packages/Castle.Core) as my weapon of choice.
Naive implementation
This is what we're going for at this stage:
Foo foo = Foo.Factory.Create<Foo>();
foo.Bar = "Zzz"; // Runs immediately.
string bar = foo.Bar; // Blocks until initialisation has completed.
Let's leave out inheritance for now (pretend that Foo is sealed).
We want Foo to have no public constructors forcing the consumer to instantiate it via Foo.Factory.Create<Foo>(), which returns a dynamic proxy derived from Foo with an additional bit of functionality injected into every virtual property getter invocation: wait for the initialisation tasks to complete.
using System.Collections.Generic;
using System.Threading.Tasks;
using Castle.DynamicProxy;
public class Foo
{
// Fields.
protected readonly List<Task> InitialisationTasks = new List<Task>();
// Properties.
// These have to be declared virtual
// in order for dynamic proxying to work.
public virtual string Bar { get; set; }
protected Foo()
{
// Initialisation work.
this.InitialisationTasks.Add(Task.Delay(500));
}
// Responsible for instantiating dynamic
// proxies of Foo and its derivatives.
public static class Factory
{
// Static fields.
static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
static readonly WaitForInitInterceptor Interceptor = new WaitForInitInterceptor();
// Factory method.
public static T Create<T>() where T : Foo
{
return ProxyGenerator.CreateClassProxy<T>(Interceptor);
}
class WaitForInitInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Applies to getters only.
if (invocation.Method.Name.StartsWith("get_"))
{
var foo = invocation.InvocationTarget as Foo;
if (foo != null)
{
// Block until initialisation completes.
Task.WhenAll(foo.InitialisationTasks).Wait();
}
// Continue to the target method.
invocation.Proceed();
}
}
}
}
}
So far so good, but by the sound of it we'll also have to deal with inheritance. The existing design will not support that, because:
the derived class can introduce a public constructor thereby bypassing proxy creation via Foo.Factory.Create<Foo>() - we need to disallow that.
any properties in a derived type need to declared virtual so that their getter invocations can be intercepted by the proxy.
Tweaking to support inheritance
Reflection to the rescue:
public class Foo
{
// Fields.
protected readonly List<Task> InitialisationTasks = new List<Task>();
// Properties.
// These have to be declared virtual
// in order for dynamic proxying to work.
public virtual string Bar { get; set; }
protected Foo()
{
// Enforce proxy integrity.
this.Validate();
// Initialisation work.
this.InitialisationTasks.Add(Task.Delay(500));
}
private void Validate()
{
var type = ProxyUtil.GetUnproxiedType(this);
// No public constructors.
if (type.GetConstructors().Length != 0)
{
throw new InvalidOperationException(
"Public constructors not supported in derived types."
);
}
// No non-virtual properties.
foreach (var property in type.GetProperties())
{
// We're only interested in getters.
var method = property.GetGetMethod();
if (method != null && !method.IsVirtual)
{
throw new InvalidOperationException(
"Only virtual properties are supported."
);
}
}
}
// Responsible for instantiating dynamic
// proxies of Foo and its derivatives.
public static class Factory
{
// Static fields.
static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
static readonly WaitForInitInterceptor Interceptor = new WaitForInitInterceptor();
// Factory method.
public static T Create<T>() where T : Foo
{
return ProxyGenerator.CreateClassProxy<T>(Interceptor);
}
class WaitForInitInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Applies to getters only.
if (invocation.Method.Name.StartsWith("get_"))
{
var foo = invocation.InvocationTarget as Foo;
if (foo != null)
{
// Block until initialisation completes.
Task.WhenAll(foo.InitialisationTasks).Wait();
}
// Continue to the target method.
invocation.Proceed();
}
}
}
}
}
Now if we were to create class FooDerived : Foo which has a public constructor or non-virtual properties (properties that don't have a getter are exempt from this rule), the base constructor will throw thereby forcing the consumer to use Foo.Factory.Create<FooDerived>().
If FooDerived needs to perform its own asynchronous initialisation work, it can just add its own tasks to InitialisationTasks - any property getter will block until all of them have completed.
This code is a bit rough due to each 'Foo' proxy initialisation doing a lot of intensive work behind the covers (via Validate). In an ideal world I would have some kind of cache (perhaps a dictionary) of types which have already passed the validation, and skip the slow Reflection-bound validation for those.
Alternative approach
While dynamic proxies are fun, the design is flawed. The concerns are not well-separated. Foo shouldn't really be worrying about pulling out its own data in the first place, and definitely shouldn't be worrying about Tasks, thread pool and the like. This was discussed extensively in the comments, and I think your best bet really is to kick off the data loading tasks at the point where you have enough information to do so, save the Task references (or whatever other async unit of work you're using), and then await them (or block by getting Result or calling Wait) when you need to use the fully-loaded instance. This ensures that your Foo instances are not accessible until the loading is fully finished and gives you reasonable control over how the async object loading is scheduled. You could, for example, roll your own limited concurrency scheduler, or use ConcurrentExclusiveSchedulerPairs ExclusiveScheduler to ensure that you are not flooding the thread pool with work. Batching object loading (using Task<IEnumerable<Foo>> instead of IEnumerable<Task<Foo>>, for example) is another good way of keeping tabs on the number of tasks you create. It's easy to get creative with async loading once you decouple it from your object construction logic, and it's almost certainly the right way to go.
Related
I have a class instance (Eli) which is used in multiple contexts, and which needs to log messages, independent of (but correctly in each) context:
public class Eli
{
void LogMessage(string msg)
{
///what to do here?
}
public void GrillTheCat()
{
LogMessage("I deed it";)
}
}
public class EliWrapper
{
Eli _eli;
Action<string> _logAction;
public EliWrapper(Eli eli, Action<string> logAction)
{
_eli = eli;
_logAction = logAction;
}
public void GrillTheCat()
{
_eli.GrillTheCat(); //I want LogMessage in Eli to invoke the _logAction of this calling instance
}
}
var eli = new Eli();
var wrapper1 = new EliWrapper(eli, msg => Console.WriteLine(msg));
var wrapper2 = new EliWrapper(eli, msg => File.AppendAllText(msg + "\n"));
I realize I could pass in the logger to the GrillTheCat function, but in my real situation, Eli has >10 functions and I don't want to clutter up all of the function signatures just for the sake of logging.
I also realize I could define a LogAction property on Eli, then have the wrappers assign their _logAction value to that property prior to invoking Eli's function, but again I have many functions and it would be somewhat tedious to wrap each one.
What I'm hoping for is a reflection-based solution where Eli's LogMessage function just steps up a couple layers of the call stack, and accesses the wrapper instance's _logAction directly.
What I'm hoping for is a reflection-based solution where Eli's LogMessage function just steps up a couple layers of the call stack, and accesses the wrapper instance's _logAction directly.
I wasn't able to find any reasonable way to access instances outside the current executing method without you heavily modifying signatures(you stated you didn't want to do).
Although I generally would not recommend what you're trying to do because of the tight coupling and general lack of extensibility and intuitiveness - However, I figured out a solution that almost fits the bill.
It is not possible, at least from what I was able to research, to access instance data from calling members. Which is to say you can't walk back up the stack and access instanced variables or objects all will-nilly, unless you explicitly capture and pass them down the stack as you're - err.. um "stacking"?.
The way we work around this is simply by declaring your _logAction as a static member. That way we don't need to access the instance you have of EliWrapper.
What this doesn't do for you is allow you to have multiple EliWrappers with different _logAction's becuase they're static.
Unfortunately without access to the individual instance(which you can't get from the stack - there's no way for Eli to know what EliWrapper wants to do without at least some of the modifications you explicitly wanted to avoid(In my opinion).
Where do we go from here?
Consider
Consider Modifying Eli so it can be used as a base-class that has different versions that log things differently.
Consider Modifying Eli to implement overrides that accept a Action<string> as a override for it's default logging.
Alternatively, but not recommended
Pass the instance of the caller to Eli so it can access instanced(non-static) members on EliWrapper so you don't need to make _logAction static(this would be a simple modification to the code i have provided to you, but would require changing all of Eli's signatures to accommodate object caller.
Store instances of EliWrapper somewhere you can access without instance, such as a static class, where you can access their instance data using reflection without explicitly passing their instances to Eli
Here's the script to access the static field using the stack
public class Eli
{
private readonly Action<string> DefaultLogger = (s) => Console.WriteLine(s);
void LogMessage(string msg)
{
// get the stack so we can get advanced information about
// who called us (CallerMemberNameAttribute was another alternative, but would incur more complex code)
StackTrace stack = new(false);
// step 2 frames up(or however many to get out of Eli and back to the 'caller'
var caller = stack.GetFrame(2)?.GetMethod()?.DeclaringType;
if (caller != null)
{
// check to see if the type that called GrillTheCat()
// has a static private field with the name '_logAction'
var possibleLoggerInCaller = caller.GetField("_logAction", BindingFlags.Static | BindingFlags.NonPublic);
if (possibleLoggerInCaller != null)
{
// get the static value of that field
var possibleLogger = possibleLoggerInCaller.GetValue(null);
// verify that the type of that logger is infact a Action<string>
// since that's what we use to log
if (possibleLogger is Action<string> logger)
{
// log the msg using the overriden logger instead of the default one
logger.Invoke(msg);
return;
}
}
}
// if we got here there wasn't a _logAction in the call stack at frame 2
// so give up and use our default logger
DefaultLogger.Invoke(msg);
}
public void GrillTheCat()
{
LogMessage("I deed it");
}
}
public class EliWrapper
{
Eli _eli;
private static Action<string> _logAction;
public EliWrapper(Eli eli, Action<string> logAction)
{
_eli = eli;
_logAction = logAction;
}
public void GrillTheCat()
{
_eli.GrillTheCat(); //I want LogMessage in Eli to invoke the _logAction of this calling instance
}
}
For my needs, I've gone with throwing exceptions. This procedurally does what I asked: only notifies the calling instance of the message, and requires no modification of function signatures.
Consider implementing a decorator for Eli that implements logging. Here is a rudimentary example that demonstrates this:
// If you haven't already: define an interface for Eli
public interface IEli
{
// Define all Eli's public members
}
// Let Eli implement IEli
public class Eli : IEli
{
...
}
With the existence of the new IEli interface, you can now implement a decorator:
public class LoggingEli : IEli
{
private readonly IEli decoratee;
private readonly Action<string> logAction;
public LoggingEli(IEli decoratee, Action<string> logAction)
{
this.decoratee = decoratee;
this.logAction = logAction;
}
// Implement all IEli members by calling the log action and forwarding
// the call to the decorated IEli instance:
public object SomeEliMethod(string param1, int param2)
{
this.logAction(nameof(SomeEliMethod) + " called for " + param1);
return this.decoratee.SomeEliMethod(param1, param2);
}
// Same for all other 9 IEli methods.
}
Using the new IEli interface and the LoggingEli decorator, you can now construct the following object graph:
var eli = new Eli();
var consoleEli = new LoggingEli(eli, msg => Console.WriteLine(msg));
var fileEli = new LoggingEli(eli, msg => File.AppendAllText(msg + "\n"));
Decorators have the advantage that you are able to add behavior to a class without having to change the original class. Downside is that it is only possible to add behavior at the start or end of the original method, and the behavior only has access to all the parameters going in and out of the called method. In your case, you can't log halfway the method, and can't log anything information that is kept internal to Eli.
In case you need to log halfway or use information that is internal to Eli, you will need to inject the logger into Eli's constructor.
I'll start with a code example. I have a following class
public class Foo
{
public object DoSomething() {}
}
I also have some code that utilises method DoSomehting from class Foo.
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
foo.DoSomething();
...
foo.DoSomething();
}
}
How could I distinguish those two calls foo.DoSomething() inside the Foo class?
What I came up with is to have an identification object passed in parameters for each call to DoSomething. Then in Foo class I would store the ids and compare them when new call is made.
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
var idObjA = new IDObj(Guid.NewGuid());
foo.DoSomething(idObjA);
...
var idObjB = new IDObj(Guid.NewGuid());
foo.DoSomething(idObjB);
}
}
Maybe there is a better way to do it, or a pattern that I'm not aware of. I want the utilising code to be the least obscured so calls to the DoSomething method are as simple as possible.
To clarify my intentions. I'm implementing a message service with an ability for the user to check a checkbox on dialog box (e.g. Do not show again, or Apply to all). Code utilising the service can call the same method multiple times, to show an error message for example, but in different context. In other words, when user decided to not show that message again for particular action message box should not appear. Thus I need to know when method was called multiple times in the same context (action)
Maybe you should expand a bit on what exactly you are trying to achieve. If you're using your instantiated class like described above and are just trying to differentiate between the first and second call, you can add a respective toggle field in your Foo class:
public class Foo
{
private bool _firstCall = true;
public object DoSomething() {
if(_firstCall) {
_firstCall = false;
// first call logic
} else {
// second call logic
}
}
}
Based on the extra info in your edit, it sounds like what you perhaps need to be doing is setting a separate property in your Foo class showing whether the "apply to all" or "do not show again" option has been checked for a particular context.
Then when you call DoSomething, it can check that property to know if it should show the dialog or not.
So in the simplest case you might do something like:
public class Foo
{
public bool DoNotShow { get; set; };
public void DoSomething() {
if(this.DoNotShow == true) {
// logic
} else {
// alternative logic
}
}
}
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
foo.DoSomething();
foo.DoNotShow = true;
...
foo.DoSomething();
}
}
The value could then be toggled on and off whenever you like.
N.B. You mentioned different "contexts" in which dialogs can be turned on and off.
For this, you could consider either giving this property the ability to store values for different contexts (e.g. in something like a Dictionary, perhaps) and then passing in the current context name to the DoSomething method when it's called. Or even pass in a totally separate "context" object to DoSomething each time, which contains the context name and the boolean indicating whether to show the dialog or not.
Or...using a different instance of Foo for each context might actually be more in line with object-oriented principles (in which case you could probably use the code exactly as per my example above). Again it depends exactly how the class the and the overall application works.
If knowing the line number of the call helps, you could use one of the methods for getting the caller information described here. So for example:
public class Foo
{
public object DoSomething() {
StackFrame frame = new StackFrame(1, true);
var method = frame.GetMethod();
var lineNumber = frame.GetFileLineNumber();
}
}
My application contains one base class called Statistic and three classes which inherit from it: LSP, CPU, Memory. I also have an additional class called ExecuteRequest whose constructor takes either an instance of Statistic or one of the more derived types (LSP, CPU or Memory). What I want to do is: determine what type of object it is (whether LSP, CPU or Memory).
To accomplish this, I created the DeterminateKpiType method which would check the incoming Statistic instance and cast it to a specific property of that type. Once complete, this specific object will be passed to the RunRequest() method. Unfortunately I encountered a problem while attempting to solve this.
I received errors (when invoking DeterminateKpiType()) saying that it cannot return those types and I have no clue how to pass the object to the RunRequest() method. How can I achieve this result? If something is unclear feel free to revert/ask.
Here is the code listing:
class ExecuteRequest
{
public Statistic KPI { get; set; }
public LSP LSP { get; set; }
public CPU CPU { get; set; }
public Memory Memory { get; set; }
public ExecuteRequest(Statistic kpi)
{
KPI = kpi;
specificStatisticKPI = DeterminateKpiType(KPI);
RunRequest(specificStatisticKPI)
}
public T DeterminateKpiType<T>(Statistic KPI)
{
if (KPI.GetType() == typeof(LSP))
{
LSP = KPI as LSP;
return LSP;
}
if (KPI.GetType() == typeof(CPU))
{
CPU = KPI as CPU;
return CPU;
}
if (KPI.GetType() == typeof(Memory))
{
Memory = KPI as Memory;
return Memory;
}
}
public void RunRequest(specificStatisticKPI what type ?????)
{
specificStatisticKPI.SomeMethod
}
}
i have a few theories i dont if it would help but i would love to tell you, first specificStatisticKPI what type is it? if its set to be Statistic type i think you need to convert it or it cant contain Memory , LSP or CPU, that is one secondly the RunRequest() method should be able to take three types of classes or the classes can be converted to each other implicitly if these things are handled i believe you code should work .
best of luck
There are a couple of challenges with the approach you're taking (and I suspect that these are causing some of the confusion you're facing) so I will try to outline these and offer solutions that should give you the results you are seeking.
Challenge 1:
You're doing way too much logic in the constructor of your ExecuteRequest class. Constructors should be limited to EXTREMELY simple conditional checks (if any) and should most certainly not perform any operations. Here you would have at least two options:
Refactor your ExecuteRequest class to be a static class with no constructor (I don't see a reason based on your current code to have it be an instantiatable type) and a static method that accepts a Statistic instance as an argument (your RunRequest method for example).
Change the constructor to only initialize the Statistic instance and make the code that consumes ExecuteRequest makes the call to RunRequest.
Of particular note on constructors (taken from MSDN links below):
...The use of public fields is not a recommended programming practice
because it allows any method anywhere in a program unrestricted and
unverified access to an object's inner workings. Data members should
generally be private, and should be accessed only through class
methods and properties.
and
Do minimal work in the constructor. Constructors should not do much
work other than to capture the constructor parameters. The cost of any
other processing should be delayed until required.
Here are some helpful guidelines for constructors and how best to use them:
http://msdn.microsoft.com/en-us/library/ms229060(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/k6sa6h87(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/ms229060(v=vs.100).aspx
Challenge 2:
Using generics and conditional type logic are usually mutually exclusive (where one option is favored over the other) and combining the two is often a Code Smell. When using generics one of the benefits come from the use of 'generic type constraints'. These constraints allow you to know as much as possible about all potential incoming implementations of a base type while allowing new instances to be created without having to modify the code. The idea is essentially one of Liskov Substitution.
For more information on generic type constraints, see: http://msdn.microsoft.com/en-us/library/d5x73970.aspx
Here is an excerpt from the MSDN documentation:
By constraining the type parameter, you increase the number of
allowable operations and method calls to those supported by the
constraining type and all types in its inheritance hierarchy.
Therefore, when you design generic classes or methods, if you will be
performing any operation on the generic members beyond simple
assignment or calling any methods not supported by System.Object, you
will have to apply constraints to the type parameter.
Possible Solutions
There are always many ways to solve a programming problem like this, here are two variations that should address the challenges you are facing.
Note: I created these in LinqPad so they are all tested to work (but your actual classes may differ from mine).
Variation 1 (Instantiatable ExecuteRequest with a class-wide generic type constraint):
void Main() {
LSP lspStatistic = new LSP();
Memory memoryStatistic = new Memory();
CPU cpuStatistic = new CPU();
ExecuteRequest<CPU> cpuRequest = new ExecuteRequest<CPU>(cpuStatistic);
ExecuteRequest<LSP> lspRequest = new ExecuteRequest<LSP>(lspStatistic);
ExecuteRequest<Memory> memoryRequest = new ExecuteRequest<Memory>(memoryStatistic);
cpuRequest.RunRequest();
lspRequest.RunRequest();
memoryRequest.RunRequest();
}
public class ExecuteRequest<TStatistic> where TStatistic : Statistic {
private TStatistic _kpi; //Whichever type the class was created as. This enables us to have intellisense support for the specific generic type outside of this class if we need it.
//Hide the default constructor from the outside world (require a statistic)
private ExecuteRequest() : this(null) {
} // end default constructor
public ExecuteRequest(TStatistic kpi) {
_kpi = kpi;
} // end overloaded constructor
public void RunRequest() {
this.KPI.SomeMethod(); //Since we know that KPI will be AT LEAST a Statistic as specified by the generic type constraint, we can access the base class members here without having to figure out which type it is because we don't actually care what type it is, just that it is a Statistic
} // end method RunRequest
public TStatistic KPI {
get {
return _kpi;
} set {
_kpi = value;
}
} // end property KPI
} // end class ExecuteRequest
public abstract class Statistic {
protected Statistic() {
} // end default constructor
public abstract void SomeMethod();
} // end class Statistic
public class LSP : Statistic {
public LSP() : base() {
} // end default constructor
public override void SomeMethod() {
Debug.WriteLine("This is the LSP implementation of SomeMethod.");
} // end method SomeMethod
} // end class LSP
public class CPU : Statistic {
public CPU() : base() {
} // end default constructor
public override void SomeMethod() {
Debug.WriteLine("This is the CPU implementation of SomeMethod.");
} // end method SomeMethod
} // end class CPU
public class Memory : Statistic {
public Memory() : base() {
} // end default constructor
public override void SomeMethod() {
Debug.WriteLine("This is the Memory implementation of SomeMethod.");
} // end method SomeMethod
} // end class Memory
Outputs:
This is the CPU implementation of SomeMethod.
This is the LSP implementation of SomeMethod.
This is the Memory implementation of SomeMethod.
Variation 2 (Static ExecuteRequest with a generic type argument and constraint):
void Main() {
LSP lspStatistic = new LSP();
Memory memoryStatistic = new Memory();
CPU cpuStatistic = new CPU();
ExecuteRequest.RunRequest<LSP>(lspStatistic);
ExecuteRequest.RunRequest<Memory>(memoryStatistic);
ExecuteRequest.RunRequest<CPU>(cpuStatistic);
}
public static class ExecuteRequest {
public static void RunRequest<TStatistic>(TStatistic statInstance) where TStatistic : Statistic {
if(statInstance != null) {
statInstance.SomeMethod();
} // end if
} // end method RunRequest
} // end class ExecuteRequest
Outputs:
This is the LSP implementation of SomeMethod.
This is the Memory implementation of SomeMethod.
This is the CPU implementation of SomeMethod.
As an alternative, since with the static implementation you don't need intellisense, you could omit the generic all-together like so:
void Main() {
LSP lspStatistic = new LSP();
Memory memoryStatistic = new Memory();
CPU cpuStatistic = new CPU();
ExecuteRequest.RunRequest(lspStatistic);
ExecuteRequest.RunRequest(memoryStatistic);
ExecuteRequest.RunRequest(cpuStatistic);
}
public static class ExecuteRequest {
public static void RunRequest(Statistic statInstance){
if(statInstance != null) {
statInstance.SomeMethod();
} // end if
} // end method RunRequest
} // end class ExecuteRequest
Hopefully this gives you some guidance on how to move forward.
I have an object pool, and I need to call a delegate method OnFree(), whenever I call Free() on an object in the pool.
Free() is created externally and set on the object when the pool is created. OnFree differs from one object to another, and sometimes it is even null.
Objects in the pool inherit from the Poolable class.
class Poolable
{
public Action Free();
public Action OnFree();
}
Currently I create OnFree in the inheriting class by doing this:
class Light
{
public Light()
{
// Create method to be called when Free() is called on this light.
OnFree = () =>
{
DoStuffHere();
};
}
}
However, this will create a separate delegate for each light, which wastes a bunch of memory especially when there are tens of thousands of objects in the pool. Er, it does create a new delegate every time this constructor is called, right?
What is a good way to allow objects to create their own OnFree() delegate, so that there is only one delegate per object type, instead of one delegate per instance?
I can think of a way of course, but I'm hoping someone can think of a "good" way -- something that allows easy maintainability.
Edit: Can I make the OnFree() delegate static in the base class, so that it is static per inherited type somehow?
Edit: To clarify how Pool is used, and why Free() is a delegate, not a virtual method. Please let me know if you can think of a better way to do this.
public class Pool<T> where T : Poolable
{
private int _liveCount;
private T[] _pool;
[...]
public Pool(int capacity, Func<T> allocateFunction)
{
[...]
// Fill pool with initial items:
for (int i = 0; i < capacity; i++)
{
T item = _allocate();
item.Free = () => Free(item);
_pool[i] = item;
}
}
/// <summary>
/// Frees given object from this pool. Object is assumed to
/// be in this pool.
/// </summary>
public void Free(Poolable obj)
{
obj.OnFree();
_liveCount -= 1;
[...]
}
}
How about keeping it simple:
class Poolable
{
public virtual void Free() { }
public virtual void OnFree() { } // naming not according to BCL std
}
class Light : Poolable
{
public override void Free() { }
...
}
your example shows no need for delegates (over virtual methods)
proper encapsulation would require events instead of public delegates
looks like you are optimizing prematurely.
It actually depends on where DoStuffHere() is defined. If this is an instance method, there is an implicit capture of this onto a compiler-generated type; likewise anything else (not shown in your example) might be captured.
In most normal cases the extra overhead of a delegate instance is minimal. One workaround to avoid passing creating a delegate is to have a parameterised delegate (an Action<SomeStateType>, perhaps stored in a static field), and feed the state in as a separate parameter... but of course, then you are creating an object for the state! The slight advantage of doing a manual capture is that you are probably (it depends on the exact code sample) reducing it from 2 (or more) allocations (1 delegate, 1-or-more capture classes) to 1 allocation (your manual capture; the delegate being held on a static field).
One way of another, there is likely going to be something created. Personally, until your profiling shows it is a bottleneck, I think you should relax a bit - allocations are very fast, and most times the object will be collected in GEN-0, which is very efficient.
If you use a static generic class you get one "instance" per type - which is exactly what you were after. Hence, using such a class as the backstore for your type-specific delegates, and initialize them in the static constructor of each Poolable sub-class would solve your problem. See the sample code:
public class Poolable
{
public Action Free { get; set; }
public Action OnFree { get { return GetOnFree(); } }
protected virtual Action GetOnFree() { throw new NotImplementedException(); }
}
public static class PoolHelper<T> where T : Poolable
{
public static Action OnFree { get; set; }
}
public class Light : Poolable
{
static Light()
{
PoolHelper<Light>.OnFree = () =>
{
// Define 'OnFree' for the Light type here...
// and do so for all other other sub-classes of Poolable
};
}
protected override Action GetOnFree()
{
return PoolHelper<Light>.OnFree;
}
}
I have the need to extend instances of various types at runtime. Most of the time, I need to work with instances of the original type, however in a few circumstances, I need to create kind of an extension-wrapper around those types that add a couple pieces of contextual information. Something along the lines of the following (which is not actually valid .NET/C# code...but it illustrates the point):
public abstract class BaseClass
{
// ...
}
public class Concrete1: BaseClass
{
// ...
}
public class Concrete2: BaseClass
{
// ...
}
public class WrapperExtender<T>: T // Extending from T here is actually invalid!
where T: BaseClass
{
public WrapperExtender(T extensionTarget)
{
m_extensionTarget = extensionTarget;
}
private readonly T m_extensionTarget;
public object ContextualReference { get; }
public int ContextualValue { get; }
// DERP: Would need to implement overrides of T here...buuut...can't...
}
// In use, special case:
var instance = new Concrete1();
var extendedInstance = new WrapperExtender(instance);
var processor = new SomeProcessorRequiringExtendedInstance();
processor.DoProcessing(extendedInstance);
Another example of this would probably be Microsoft Entity Framework v4.0, or nHibernate. Both of these frameworks provide dynamically extended instances of your entity types, wrapping them internally to provide, at runtime, the hooks required to keep a data/object/session context up to date with changes made to your entity instances. My needs are not nearly as complex, and the generics scenario above would work beautifully, if only there was a way to blend generics and dynamic typing somehow.
Anyway, I'm hoping someone knows how to achieve the above scenario. Or, perhaps even better, someone knows a better solution. I don't care much for the idea of dynamically extending a type like that at runtime (it doesn't make as much sense as it does in the EF/nHibernate scenario.) At the moment, its the only thing I can really think of that will provide me with the information I need in the processor for each type passed in to DoProcessing.
The problems that EF etc are solving is different, and relates to tihngs like lazy loading, etc. I'm simply not sure that the level of complexity that dynamic subclassing requires is worth it for this scenario. A few thoughts, though:
have a property bag in your object for flexible additional properties; if necessary the property-bag can be exposed to data-binding APIs via ICustomTypeDescriptor
simply wrap your object in an implementation-specific tuple that contains the existing object and the additional properties (no subclassing)
It is a shame that C# doesn't support "mixins", which would also be a nice way of implementing this type of thing with interfaces.
I know that this can be accomplished using dynamicproxy (which is what NHibernate uses to accomplish this task) which you can find out more about here:
DynamicProxy Page
DynamicProxy tutorial
If all you need is some additional properties, why not just create a context property in BaseClass?
something like this, where ContextBag is either a generic collection class or specially defined context collection:
Public ContextBag Context
{
get;
set;
}
When setting/accessing the context, you will be using syntax like this:
SubClass.Context.GetInt(ContextDefinition, ContextName);
SubClass.Context.Add(ContextDefinition, ContextName, ContextValue);
Found a better solution than temporarily extending. I created an actual context object that contained the state I needed available. Whenever that context exists, I initialize the context and set a static property that can be used to retrieve the context object from anywhere, alleviating the need to update all the dependencies of my larger process to take the context in as a parameter (which isn't always possible, as sometimes the calls are made in other contexts.)
public class SomeContext
{
public SomeContext(object stateData1, object stateData2)
{
StateData1 = stateData1;
StateData2 = stateData2;
}
public virtual object StateData1 { get; private set; }
public virtual object StateData2 { get; private set; }
[ThreadStatic]
private static SomeContext m_threadInstance;
public static SomeContext Current
{
get
{
return m_threadInstance;
}
set
{
if (value != null && m_threadInstance != null)
throw new InvalidOperationException("This context has already been initialized for the current thread.");
m_threadInstance = value;
}
}
}
public class SomeContextScope: IDisposable
{
public SomeContextScope(object stateData1, object stateData2)
{
if (SomeContext.Current == null)
{
SomeContext context = new SomeContext(stateData1, stateData2);
SomeContext.Current = context;
m_contextCreated = true;
}
}
private bool m_contextCreated;
public void Dispose()
{
if (m_contextCreated)
{
SomeContext.Current = null;
}
}
}
public class ComplexProcessor
{
public ComplexProcessor(...) // Lots of dependencies injected
public void DoProcessing(BaseClass instance)
{
// do some work with instance
if (SomeContext.Current != null)
{
// do contextually sensitive stuff for SomeContext with instance
// call a dependency that does contextually sensitive stuff
}
// do some more work with instance
// call a dependency that does contextually sensitive stuff
if (SomeOtherContext.Current != null)
{
// do contextually sensitive stuff for SomeOtherContext with instance
// call a dependency that does contextually sensitive stuff
}
// call a dependency that does contextually sensitive stuff
}
}
// The original setup of the context and initiation of processing
public void SomeOperation(...)
{
using (SomeContextScope scope = new SomeContextScope(stateData1, stateData2))
{
// ... do some work
var processor = complexProcessorFactory.CreateInstance();
processor.DoProcesing(data);
// ... do more work
}
}
I like the way this works. Context is the state within which behavior executes. It has always felt clunky to me to have to pass contextual data around with other objects, and have dozens of methods or method overloads that take in and pass along various forms of contextual data. By setting up a context object that is globally available for the duration of that context, my code is a lot cleaner, and my dependencies are more concise. It should be mockable too, since the Current property is read/write, I can create a mock context in a BDD specification or TDD unit test whenever one is required without a lot of hassle.