Get a reference to the object that called a method? - c#

I have a dll that includes:
public abstract class Module
{
internal int ID;
public abstract void ModuleStart();
}
public void function1() {}
public void function2() {}
//etc...
And then I have another dll that references the above dll and has:
class MyModule : Module
{
public override void ModuleStart()
{
function1();
}
}
What I'd like to be able to do is have function1 known the value of the calling module's ID, without it being passed in. Is there a way to do this? Basically what I'm trying to do is, the main Module DLL is loaded up, a method is run that loads in the second dll, uses reflection to make sure it has a child of Module, assigns it an ID and runs ModuleStart. MyModule can then do what it needs, calling functions from the first dll in order to access internal protected memory, but when the functions are called they need to know the ID of the Module that called them. Is this possible? MyModule has no knowledge of its ID, nor an ability to change it.

.NET 4.5 adds some functionality to do something similar to this with the CallerMemberNameAttribute. Here's a sample from the docs:
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}

A few people have suggested using the call stack to get the module information. If you want to get the type of object that made the call, it's not too bad. Unfortunately there is no feasible (ie: simple, portable and functional) method to extract instance information from data in the call stack. There are several reasons why, including problems with optimization inlining methods that then do not show on the stack... which can interfere with calling type detection as well.
Given this fact, the short answer is that you have to provide a Module object as a parameter to the methods you are calling in the DLL. The method suggested by #p.s.w.g is one way of achieving this, but has the disadvantage of potentially polluting the symbol space of the Module class. This can be solved by having the Module class implement a protected or public API member that exposes the functions you want to provide:
public abstract class Module
{
internal int ID;
public class APIWrapper
{
Module module;
public APIWrapper(Module module)
{
this.module = module;
}
public void method1() { apiimpl.method1(this.module); }
public int method2() { return apiimpl.method2(this.module); }
}
public readonly APIWrapper API;
public Module()
{
ID = generate_module_identity();
API = new APIWrapper(this);
}
public abstract void ModuleStart();
}
internal static class apiimpl
{
public static void method1(Module module) { ... }
public static int method2(Module module) { ... }
}
The other developers can then use it this way:
class MyModule : Module
{
public override void ModuleStart()
{
API.method1();
}
}
This encapsulates the methods that your DLL exposes, without introducing too much pollution of the symbol space of the Module class hierarchy.
[opinion type="my" value="YMMV"]
However, I suggest that you seriously reconsider using this type of abstraction. If the methods you are calling require some information about the specific Module instance that is calling them, it should be clear in the method's parameters. Encouraging your team to follow guidelines that lead to clarity can be more important than finding ways to abstract away small details.
[/opinion]

If what you really want is just to retrieve the ID at run-time, without passing any arguments into function1, you can use inherited methods:
public abstract class Module
{
internal int ID;
public abstract void ModuleStart();
protected void function1()
{
System.Console.WriteLine ("function1 called from module {0}", this.ID);
}
}
Then, from your other modules, calling function1 looks as simple as this:
class MyModule : Module
{
public override void ModuleStart()
{
this.function1(); // the 'this.' is not required
}
}
However, I get the sense from your comments that you want to make keep these functions separate from your Module class, since you are routinely adding new functions. You can do almost the exact same thing using extension methods to maintain the appearance of not passing any parameters:
public abstract class Module
{
internal int ID;
public abstract void ModuleStart();
}
public static class ModuleExtensions
{
public static void function1(this Module module)
{
innerFunction1(module.ID);
}
internal static void innerFunction1(int ID)
{
System.Console.WriteLine ("function1 called from module {0}", ID);
}
}
Then, from your other modules, calling function1 looks as simple as this:
class MyModule : Module
{
public override void ModuleStart()
{
this.function1(); // the 'this.' is required
}
}

Related

How can I get the function/action name that custom attribute is attached to while it is executing?

Ideally, I want to create a filter that inherits from ActionFilterAttribute that I can apply in Global.asax that will create performance counters for all the actions in my application. That problem is easy, but the issue is that I want the performance counters to have the method signature of the action that they are attached to in their name. However, I can't find a way to extract the method name of the method that an attribute is attached to during construction. This is causing me to have to apply the attributes to each action individually and pass in their signature as a parameter. However, this poses obvious problems (i.e. updates to method signature not automatically synchronized with perf counter naming).
To simplify the problem, if I attach an attribute to a method of any kind, can I access the name/signature of the method that it is attached to? I'm looking for a generic solution that works for attributes that don't derive from ActionFilterAttribute also.
public class SomeAttribute : ActionFilterAttribute
{
public string FunctionSignature { get; set; }
public SomeAttribute()
{
this.FunctionName = { HOW DO I GET THE NAME OF THE METHOD I'M ON WITHOUT PASSING IT IN AS AN INPUT ARGUMENT? }
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Some code to update perf counter(s) with recorded time that will use string.Format("{0}: Avg. Time or Something", this.FunctionSignature).
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Some code to record time.
}
}
[SomeAttribute]
public void SomeMethod()
{
// Some code.
}
Find the name of executing action:
var actionName = filterContext.ActionDescriptor.ActionName;
or alternatively
var actionName = filterContext.RouteData.Values["action"] as string
Find parameters (Name, Type, DefaultValue):
var parameters = filterContext.ActionDescriptor.GetParameters();
Find parameters values:
var value= filterContext.ActionParameters["parameterName"];
As I understand, you want generic solution for that, not related to ActionFilterAttribute or asp.net at all. Then you can use Aspect Oriented Programming, and best implementation of that for .NET is PostSharp. Free version of that library is enough to achieve your goal. For example:
class Program
{
static void Main(string[] args)
{
Test();
Console.ReadKey();
}
[Measure]
public static void Test() {
Thread.Sleep(1000);
}
}
[Serializable]
public sealed class MeasureAttribute : OnMethodBoundaryAspect
{
private string _methodName;
[NonSerialized]
private Stopwatch _watch;
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo) {
base.CompileTimeInitialize(method, aspectInfo);
// save method name at _compile_ time
_methodName = method.Name;
}
public override void OnEntry(MethodExecutionArgs args) {
base.OnEntry(args);
// here you have access to everything about method
_watch = Stopwatch.StartNew();
}
public override void OnExit(MethodExecutionArgs args) {
base.OnExit(args);
if (_watch != null) {
_watch.Stop();
Console.WriteLine("Method {0} took {1}ms", _methodName, _watch.ElapsedMilliseconds);
}
}
public override void OnException(MethodExecutionArgs args) {
base.OnException(args);
// do what you want on exception
}
}
Here we create MeasureAttribute which you can apply on any method and intercept method invocation in many points. Even more, you can even apply it dynamically to all methods based on some condition (i.e. all methods in given class or whole assembly, or whatever). It also allows you to save some information in compile time, to increase perfomance. In example above we save method name once during compilation.
PostSharp (and AOP in general) can do much more than that.
I assume that your method name will be the same as filterContext.ActionDescriptor.ActionName.
And you can get the Controller instance from filterContext.Controller.
So having class and method name you can get the signature, however not in the constructor.
I can imagine two alternatives. You could reflect on all the types in classes in loaded assemblies - not very direct but works. Problem is - I'm not sure if the interesting assemblies are even loaded in time - you might have to proactively load them using config information as a guide.
The attributes can be queries on the various MethodInfo/PropertyInfo objects that you can interrogate reflectively. Then, the attributes are queried with MemberInfo.GetCustomeAttributes.
Alternatively, instead of global.asax, you could have the interesting types register themselves for inspection during their static initialization.

Some design-pattern suggestions needed

C#. I have a base class called FileProcessor:
class FileProcessor {
public Path {get {return m_sPath;}}
public FileProcessor(string path)
{
m_sPath = path;
}
public virtual Process() {}
protected string m_sath;
}
Now I'd like to create to other classes ExcelProcessor & PDFProcessor:
class Excelprocessor: FileProcessor
{
public void ProcessFile()
{
//do different stuff from PDFProcessor
}
}
Same for PDFProcessor, a file is Excel if Path ends with ".xlsx" and pdf if it ends with ".pdf". I could have a ProcessingManager class:
class ProcessingManager
{
public void AddProcessJob(string path)
{
m_list.Add(Path;)
}
public ProcessingManager()
{
m_list = new BlockingQueue();
m_thread = new Thread(ThreadFunc);
m_thread.Start(this);
}
public static void ThreadFunc(var param) //this is a thread func
{
ProcessingManager _this = (ProcessingManager )var;
while(some_condition) {
string fPath= _this.m_list.Dequeue();
if(fPath.EndsWith(".pdf")) {
new PDFProcessor().Process();
}
if(fPath.EndsWith(".xlsx")) {
new ExcelProcessor().Process();
}
}
}
protected BlockingQueue m_list;
protected Thread m_thread;
}
I am trying to make this as modular as possible, let's suppose for example that I would like to add a ".doc" processing, I'd have to do a check inside the manager and implement another DOCProcessor.
How could I do this without the modification of ProcessingManager? and I really don't know if my manager is ok enough, please tell me all your suggestions on this.
I'm not really aware of your problem but I'll try to give it a shot.
You could be using the Factory pattern.
class FileProcessorFactory {
public FileProcessor getFileProcessor(string extension){
switch (extension){
case ".pdf":
return new PdfFileProcessor();
case ".xls":
return new ExcelFileProcessor();
}
}
}
class IFileProcessor{
public Object processFile(Stream inputFile);
}
class PdfFileProcessor : IFileProcessor {
public Object processFile(Stream inputFile){
// do things with your inputFile
}
}
class ExcelFileProcessor : IFileProcessor {
public Object processFile(Stream inputFile){
// do things with your inputFile
}
}
This should make sure you are using the FileProcessorFactory to get the correct processor, and the IFileProcessor will make sure you're not implementing different things for each processor.
and implement another DOCProcessor
Just add a new case to the FileProcessorFactory, and a new class which implements the interface IFileProcessor called DocFileProcessor.
You could decorate your processors with custom attributes like this:
[FileProcessorExtension(".doc")]
public class DocProcessor()
{
}
Then your processing manager could find the processor whose FileProcessorExtension property matches your extension, and instantiate it reflexively.
I agree with Highmastdon, his factory is a good solution. The core idea is not to have any FileProcessor implementation reference in your ProcessingManager anymore, only a reference to IFileProcessor interface, thus ProcessingManager does not know which type of file it deals with, it just knows it is an IFileProcessor which implements processFile(Stream inputFile).
In the long run, you'll just have to write new FileProcessor implementations, and voila. ProcessingManager does not change over time.
Use one more method called CanHandle for example:
abstract class FileProcessor
{
public FileProcessor()
{
}
public abstract Process(string path);
public abstract bool CanHandle(string path);
}
With excel file, you can implement CanHandle as below:
class Excelprocessor: FileProcessor
{
public override void Process(string path)
{
}
public override bool CanHandle(string path)
{
return path.EndsWith(".xlsx");
}
}
In ProcessingManager, you need a list of processor which you can add in runtime by method RegisterProcessor:
class ProcessingManager
{
private List<FileProcessor> _processors;
public void RegisterProcessor(FileProcessor processor)
{
_processors.Add(processor)
}
....
So LINQ can be used in here to find appropriate processor:
while(some_condition)
{
string fPath= _this.m_list.Dequeue();
var proccessor = _processors.SingleOrDefault(p => p.CanHandle(fPath));
if (proccessor != null)
proccessor.Process(proccessor);
}
If you want to add more processor, just define and add it into ProcessingManager by using
RegisterProcessor method. You also don't change any code from other classes even FileProcessorFactory like #Highmastdon's answer.
You could use the Factory pattern (a good choice)
In Factory pattern there is the possibility not to change the existing code (Follow SOLID Principle).
In future if a new Doc file support is to be added, you could use the concept of Dictionaries. (instead of modifying the switch statement)
//Some Abstract Code to get you started (Its 2 am... not a good time to give a working code)
1. Define a new dictionary with {FileType, IFileProcessor)
2. Add to the dictionary the available classes.
3. Tomorrow if you come across a new requirement simply do this.
Dictionary.Add(FileType.Docx, new DocFileProcessor());
4. Tryparse an enum for a userinput value.
5. Get the enum instance and then get that object that does your work!
Otherwise an option: It is better to go with MEF (Managed Extensibility Framework!)
That way, you dynamically discover the classes.
For example if the support for .doc needs to be implemented you could use something like below:
Export[typeof(IFileProcessor)]
class DocFileProcessor : IFileProcessor
{
DocFileProcessor(FileType type);
/// Implement the functionality if Document type is .docx in processFile() here
}
Advantages of this method:
Your DocFileProcessor class is identified automatically since it implements IFileProcessor
Application is always Extensible. (You do an importOnce of all parts, get the matching parts and Execute.. Its that simple!)

Composing shared parts with different export names via static properties

Needs -
To declare shared exports of the same interface. The exports are marked by unique export names so consumers may import a particular flavor of the export.
To inject a common instance of the class into a set of objects but to not share a common instance across sets of objects [This makes me use shared exports using different keys - one set of objects can use a single key to get satisfy their shared import need]
Here is the export class
public interface IMyExport
{
void Display();
}
public class MyExport : IMyExport
{
private Guid _id = Guid.NewGuid();
public void Display()
{
Console.WriteLine("Instance ID = "+_id);
}
}
and here is how I export instances of the class
public static class ExportInitialization
{
[Export("Type A", typeof(IMyExport)),
Export("Type B", typeof(IMyExport))]
public static IMyExport IceCreamExport
{
get
{
return new MyExport();
}
}
}
Consumers may import specific instances in the following manner
[Export]
public class ImporterA
{
private readonly IMyExport _myExport;
[ImportingConstructor]
public ImporterA([Import("Type A")]IMyExport myExport)
{
_myExport = myExport;
}
public void Display()
{
_myExport.Display();
}
}
[Export]
public class ImporterB
{
private readonly IMyExport _myExport;
[ImportingConstructor]
public ImporterB([Import("Type B")]IMyExport myExport)
{
_myExport = myExport;
}
public void Display()
{
_myExport.Display();
}
}
class Program
{
[Import]
public ImporterA ImporterA { get; set; }
[Import]
public ImporterB ImporterB { get; set; }
static void Main(string[] args)
{
new Program().Run();
}
public void Run()
{
var container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
container.ComposeParts(this);
ImporterA.Display();
ImporterB.Display();
Console.ReadKey();
}
}
This used to work fine with .Net 4.0 but when .Net 4.5 is installed - I get the following ouptut
Instance ID = 78bba41a-0c48-44fc-ae69-f0ead96371f9
Instance ID = 78bba41a-0c48-44fc-ae69-f0ead96371f9
Notice that the same instance of the object is returned for both imports. Am I breaking some undocumented rule regarding exporting via static properties?
I found that exporting the specific instances from two distinct static properties ensures that 2 distinct instances are returned.
[Export("Type A", typeof(IMyExport))]
public static IMyExport ExportA
{
get
{
return new MyExport();
}
}
[Export("Type B", typeof(IMyExport))]
public static IMyExport ExportB
{
get
{
return new MyExport();
}
}
This is puzzling since in the unmodified version the static getter was creating a new instance on every get. Not sure if this is the result of some C#/.Net optimization introduced with 4.5 or if this is a MEF issue
This is related to the MEF parts lifetime.
The default for MEF attributes is that components do not say whether they care to get a new instance each time or not.
Meaning that:
Your ExportAttribute does not specify whether exported instances can or should be shared;
Both of the ImportAttributes do not specify whether their import should be shared or not;
The default behavior of MEF is that, if it is not forbidden from sharing instances, it will. Meaning that, according to the documentation, the behavior of .NET 4.5 is the correct one: the instance of MyExport is shared, given that no-one on either side explicitly forbade sharing.
I think that .NET 4.0 had a bug/discrepancy where the static property was called every time, which resulted in what you observed, that is, non shared instances. And you were relying on that bug. I think that the bug finds its origin in a fundamental, framework-wide expectation for properties - it is very unusual to have a static property create a new, semantically distinct, instance for each property call.
I believe you should:
Replace your static property export with a static method export;
Specify the creation policy to non-shared, on either the Export side or the Import side;

Return an opaque object to the caller without violating type-safety

I have a method which should return a snapshot of the current state, and another method which restores that state.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
The state Snapshot class should be completely opaque to the caller--no visible methods or properties--but its properties have to be visible within the MachineModel class. I could obviously do this by downcasting, i.e. have CurrentSnapshot return an object, and have RestoreSnapshot accept an object argument which it casts back to a Snapshot.
But forced casting like that makes me feel dirty. What's the best alternate design that allows me to be both type-safe and opaque?
Update with solution:
I wound up doing a combination of the accepted answer and the suggestion about interfaces. The Snapshot class was made a public abstract class, with a private implementation inside MachineModel:
public class MachineModel
{
public abstract class Snapshot
{
protected internal Snapshot() {}
abstract internal void Restore(MachineModel model);
}
private class SnapshotImpl : Snapshot
{
/* etc */
}
public void Restore(Snapshot state)
{
state.Restore(this);
}
}
Because the constructor and methods of Snapshot are internal, callers from outside the assembly see it as a completely opaque and cannot inherit from it. Callers within the assembly could call Snapshot.Restore rather than MachineModel.Restore, but that's not a big problem. Furthermore, in practice you could never implement Snapshot.Restore without access to MachineModel's private members, which should dissuade people from trying to do so.
Can MachineModel and Snapshot be in the same assembly, and callers in a different assembly? If so, Snapshot could be a public class but with entirely internal members.
I could obviously do this by
downcasting, i.e. have CurrentSnapshot
return an object, and have
RestoreSnapshot accept an object
argument which it casts back to a
Snapshot.
The problem is that somebody could then pass an instance of an object which is not Snapshot.
If you introduce an interface ISnapshot which exposes no methods, and only one implementation exists, you can almost ensure type-safety at the price of a downcast.
I say almost, because you can not completely prevent somebody from creating another implementation of ISnapshot and pass it, which would break. But I feel like that should provide the desired level of information hiding.
You could reverse the dependency and make Snapshot a child (nested class) of MachineModel. Then Snapshot only has a public (or internal) Restore() method which takes as a parameter an instance of MachineModel. Because Snapshot is defined as a child of MachineModel, it can see MachineModel's private fields.
To restore the state, you have two options in the example below. You can call Snapshot.RestoreState(MachineModel) or MachineModel.Restore(Snapshot)*.
public class MachineModel
{
public class Snapshot
{
int _mmPrivateField;
public Snapshot(MachineModel mm)
{
// get mm's state
_mmPrivateField = mm._privateField;
}
public void RestoreState(MachineModel mm)
{
// restore mm's state
mm._privateField = _mmPrivateField;
}
}
int _privateField;
public Snapshot CurrentSnapshot
{
get { return new Snapshot(this); }
}
public void RestoreState(Snapshot ss)
{
ss.Restore(this);
}
}
Example:
MachineModel mm1 = new MachineModel();
MachineModel.Snapshot ss = mm1.CurrentSnapshot;
MachineModel mm2 = new MachineModel();
mm2.RestoreState(ss);
* It would be neater to have Snapshot.RestoreState() as internal and put all callers outside the assembly, so the only way to do a restore is via MachineModel.RestoreState(). But you mentioned on Jon's answer that there will be callers inside the same assembly, so there isn't much point.
This is an old question, but i was looking for something very similar and I ended up here and between the information reported here and some other I came up with this solution, maybe is a little overkill, but this way the state object is fully opaque, even at the assembly level
class Program
{
static void Main(string[] args)
{
DoSomething l_Class = new DoSomething();
Console.WriteLine("Seed: {0}", l_Class.Seed);
Console.WriteLine("Saving State");
DoSomething.SomeState l_State = l_Class.Save_State();
l_Class.Regen_Seed();
Console.WriteLine("Regenerated Seed: {0}", l_Class.Seed);
Console.WriteLine("Restoring State");
l_Class.Restore_State(l_State);
Console.WriteLine("Restored Seed: {0}", l_Class.Seed);
Console.ReadKey();
}
}
class DoSomething
{
static Func<DoSomething, SomeState> g_SomeState_Ctor;
static DoSomething()
{
Type type = typeof(SomeState);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
Random c_Rand = new Random();
public DoSomething()
{
Seed = c_Rand.Next();
}
public SomeState Save_State()
{
return g_SomeState_Ctor(this);
}
public void Restore_State(SomeState f_State)
{
((ISomeState)f_State).Restore_State(this);
}
public void Regen_Seed()
{
Seed = c_Rand.Next();
}
public int Seed { get; private set; }
public class SomeState : ISomeState
{
static SomeState()
{
g_SomeState_Ctor = (DoSomething f_Source) => { return new SomeState(f_Source); };
}
private SomeState(DoSomething f_Source) { Seed = f_Source.Seed; }
void ISomeState.Restore_State(DoSomething f_Source)
{
f_Source.Seed = Seed;
}
int Seed { get; set; }
}
private interface ISomeState
{
void Restore_State(DoSomething f_Source);
}
}

Internal global property..bad smell?

I have run into a bit of a desgin issue with some code that I have been working on:
My code basic looks like this:
Main COM wrapper:
public class MapinfoWrapper
{
public MapinfoWrapper()
{
Publics.InternalMapinfo = new MapinfoWrapper();
}
public void Do(string cmd)
{
//Call COM do command
}
public string Eval(string cmd)
{
//Return value from COM eval command
}
}
Public static class to hold internal referance to wrapper:
internal static class Publics
{
private static MapinfoWrapper _internalwrapper;
internal static MapinfoWrapper InternalMapinfo
{
get
{
return _internalwrapper;
}
set
{
_internalwrapper = value;
}
}
}
Code that uses internal wrapper instance:
public class TableInfo
{
public string Name {
get { return Publics.InternalMapinfo.Eval("String comman to get the name"); }
set { Publics.InternalMapinfo.Do("String command to set the name"); }
}
}
Does this smell bad to anyone? Should I be using a internal property to hold a reference to the main wrapper object or should I be using a different design here?
Note: The MapinfoWrapper object will be used by the outside world, so I don't really want to make that a singleton.
You are reducing the testability of your TableInfo class by not injecting the MapInfoWrapper into the class itself. Whether you use a global cache of these MapInfoWrapper classes depends on the class -- you need to decide whether it is necessary or not, but it would improve your design to pass a wrapper into TableInfo and use it there rather than referencing a global copy directly inside TableInfo methods. Do this in conjunction with the definition of an interface (i.e., "refactor to interfaces").
I would also do lazy instantiation in the getter(s) of Publics to make sure the object is available if it hasn't already been created rather than setting it in the constructor of MapInfoWrapper.
public class TableInfo
{
private IMapinfoWrapper wrapper;
public TableInfo() : this(null) {}
public TableInfo( IMapinfoWrapper wrapper )
{
// use from cache if not supplied, could create new here
this.wrapper = wrapper ?? Publics.InternalMapInfo;
}
public string Name {
get { return wrapper.Eval("String comman to get the name"); }
set { wrapper.Do("String command to set the name"); }
}
}
public interface IMapinfoWrapper
{
void Do( string cmd );
void Eval( string cmd );
}
public class MapinfoWrapper
{
public MapinfoWrapper()
{
}
public void Do(string cmd)
{
//Call COM do command
}
public string Eval(string cmd)
{
//Return value from COM eval command
}
}
internal static class Publics
{
private static MapinfoWrapper _internalwrapper;
internal static MapinfoWrapper InternalMapinfo
{
get
{
if (_internalwrapper == null)
{
_internalwrapper = new MapinfoWrapper();
}
return _internalwrapper;
}
}
}
Now, when you test the TableInfo methods, you can mock out the MapInfoWrapper easily by providing your own implementation to the constructor. Ex (assuming a hand mock):
[TestMethod]
[ExpectedException(typeof(ApplicationException))]
public void TestTableInfoName()
{
IMapinfoWrapper mockWrapper = new MockMapinfoWrapper();
mockWrapper.ThrowDoException(typeof(ApplicationException));
TableInfo info = new TableInfo( mockWrapper );
info.Do( "invalid command" );
}
I thought about adding this to my original response, but it is really a different issue.
You might want to consider whether the MapinfoWrapper class needs to be thread-safe if you store and use a cached copy. Anytime you use a single, global copy you need to consider if it will be used by more than one thread at a time and build it so that any critical sections (anywhere data may be changed or must be assumed to not change) are thread-safe. If a multithreaded environment must be supported -- say in a web site -- then this might argue against using a single, global copy unless the cost of creating the class is very high. Of course, if your class relies on other classes that are also not thread-safe, then you may need to make your class thread-safe anyway.

Categories