Click here to Skip to main content
15,885,244 members
Home / Discussions / C#
   

C#

 
GeneralRe: Using StreamWriter twice Pin
Covean4-Nov-09 5:12
Covean4-Nov-09 5:12 
AnswerRe: Using StreamWriter twice Pin
Pete O'Hanlon4-Nov-09 4:22
mvePete O'Hanlon4-Nov-09 4:22 
GeneralRe: Using StreamWriter twice Pin
Trollslayer4-Nov-09 5:40
mentorTrollslayer4-Nov-09 5:40 
GeneralRe: Using StreamWriter twice Pin
Pete O'Hanlon4-Nov-09 6:39
mvePete O'Hanlon4-Nov-09 6:39 
Questionsending receiving sms Pin
sahoo.fm4-Nov-09 0:33
sahoo.fm4-Nov-09 0:33 
AnswerRe: sending receiving sms Pin
King Julien4-Nov-09 0:46
King Julien4-Nov-09 0:46 
AnswerRe: sending receiving sms Pin
Giorgi Dalakishvili4-Nov-09 0:49
mentorGiorgi Dalakishvili4-Nov-09 0:49 
QuestionIs it possible to add an interface implementation to precompiled types at runtime? Pin
dojohansen4-Nov-09 0:15
dojohansen4-Nov-09 0:15 
Hi,

This very long post consists of a relatively short question and a lot of background information. Please read at least the question before deciding this isn't worth your time!

Question

Does anyone know if it's feasible to inject code into a precompiled object at runtime? I suppose it would be quite tricky, but I am not sure since the .NET Framework has surprised me many times by providing easy ways to do previously difficult things!

What I want is to have a bunch of objects implement an interface by generating this implementation at run-time. Existing instances (at the time of generating the implementation) of the type would have to be replaced by the generated type, and still be "seen" as the same type (I don't know much about how type checking is implemented in the runtime) by all the other precompiled code.

Is this possible? If so, and if anyone knows how to do it, or more likely where I can find the information I need to figure out how to do it, I'd very much appreciate the help.


Background

If anyone thinks what I am trying to do seems very odd and find themselves thinking there must be better ways to achieve the same, here's that background. The following doesn't really add to my question, although it's possible of course that there is some other way of achieving the result I desire, so I think it's worth including it.

I'm toying around with making a fairly general data access framework intended for rapid prototyping purposes. The emphasis is therefore on minimal programming and configuration (for the user of the framework), and sensible default behaviors that would work in most if not all situations but need not be optimal in terms of performance or scalability. However, I find myself thinking if I can achieve this and also get good performance, that would be pretty awesome and make the framework into something far more valuable than just a prototyping tool.

I want to completely encapsulate the storage system so it's essentially reduced to exposing just two operations: Load and Save. (Some other types would also be exposed, such as attributes to override default behaviors, a Selection type to specify a subset of objects to load at once, interfaces the entity objects may implement to optimize performance by letting the storage system ask the object if it has changed since it was loaded, and more. But only two operations: Load and Save.) When saving and loading objects I want to do so based on fields, not properties, since the fields always contain the true state of the object. The user of the framework would therefore not need to necessarily expose everything as properties that are read-write, and that's important to me, since using read-only properties is a very good way to encapsulate and protect state in many cases.

I know this can be achieved by using reflection to read and write the fields. However, I find myself thinking that if I could somehow inject change the type that is being loaded or saved at run-time so it implements a simple interface, I could instead use reflection to generate code that relies on the interface to get and set private fields of the object. This would lead to considerable overhead the first time a type is saved or loaded, but then be very fast since the generated and compiled code would simply be reused.

Here is some very very incomplete code to illustrate the idea:

// Some type a user of the framework wants to store persistently.
public class Toto
{
   int n;
   string s;
   Toto parent;

   // .. other members that we don't really care about; only fields matter.
}


public class Storage
{
   // Storage itself doesn't really have a clue how anything is stored, 
   // but it knows about an object that can generate implementations based
   // on type, it caches such generated objects, and delegates the actual
   // loading and saving to these generated objects.
   static public ObjectManagerFactory ObjectManagerFactory { get; set; }

   Dictionary<Type, IObjectManager> objectManagers;

   public List<T> Load<T>(Selection selection) 
   {
      IObjectManager m;
      Type t = typeof(T);
      if (!objectManagers.TryGetValue(t, out m))
      {
         m = ObjectManagerFactory.CreateManager(t);
         objectManagers[t] = m;
      }
      return (T)m.Load(selection);
   }

   // Similarly for Save, the implementation in Storage only sees if an ObjectManager
   // for the type already exists, and if not has the factory create one and cache
   // the result, then delegate the actual saving to the ObjectManager instance.
   public void Save(object data) { ... }
}


Now imagine my user wants to save an instance of Toto. He would have to first have instantiated the Storage class (but this is obviously intended to have the same lifetime as the application, since otherwise caching the object managers would not have as much effect), but then the code would just be something like this:

Storage.Save(toto);

What I would like to do, but doubt is actually possible, is to modify the Toto type so it becomes something like this:

public class Toto : IFieldAccessible
{
   int n;
   string s;
   Toto parent;

   object[] IFieldAccessible GetFieldValues()
   {
      return new object[] { n, s, parent };
   }

   void IFieldAccessible SetFieldValues(object[] values)
   {
      n = (int)values[0];
      s = (string)values[1];
      parent = (Toto)values[2];
   }

   // .. other members that we don't really care about; only fields matter.
}


Since the code that would use the two interface methods is also dynamically generated there should be no problem with having to rely on the index in the object arrays to know what field belongs to what value.

The trouble is I don't know if this is even possible (I doubt it!) and much less how it could be done if it is. Also, I don't think it can be done by hooking into the build process, because the types that may be loaded or saved aren't necessarily known at compile-time.
AnswerRe: Is it possible to add an interface implementation to precompiled types at runtime? Pin
PIEBALDconsult4-Nov-09 9:33
mvePIEBALDconsult4-Nov-09 9:33 
GeneralRe: Is it possible to add an interface implementation to precompiled types at runtime? Pin
dojohansen4-Nov-09 10:08
dojohansen4-Nov-09 10:08 
GeneralRe: Is it possible to add an interface implementation to precompiled types at runtime? Pin
Pete O'Hanlon4-Nov-09 10:21
mvePete O'Hanlon4-Nov-09 10:21 
GeneralRe: Is it possible to add an interface implementation to precompiled types at runtime? Pin
PIEBALDconsult4-Nov-09 10:45
mvePIEBALDconsult4-Nov-09 10:45 
GeneralRe: Is it possible to add an interface implementation to precompiled types at runtime? Pin
dojohansen4-Nov-09 13:22
dojohansen4-Nov-09 13:22 
GeneralRe: Is it possible to add an interface implementation to precompiled types at runtime? [modified] Pin
PIEBALDconsult4-Nov-09 15:07
mvePIEBALDconsult4-Nov-09 15:07 
Questionhow to use towords() function in crystal reports...... Pin
PravinYog4-Nov-09 0:14
PravinYog4-Nov-09 0:14 
QuestionChanging the colour of scroll bar Pin
deeptishete4-Nov-09 0:10
deeptishete4-Nov-09 0:10 
AnswerRe: Changing the colour of scroll bar Pin
dojohansen4-Nov-09 0:57
dojohansen4-Nov-09 0:57 
QuestionHow do you bind with a textbox to a Nullable&lt;decimal&gt; datasource property? Pin
Last Attacker3-Nov-09 23:42
Last Attacker3-Nov-09 23:42 
Questionaccessing windows controls through application Pin
Innayat Ullah3-Nov-09 23:36
Innayat Ullah3-Nov-09 23:36 
AnswerRe: accessing windows controls through application Pin
Giorgi Dalakishvili4-Nov-09 0:09
mentorGiorgi Dalakishvili4-Nov-09 0:09 
GeneralRe: accessing windows controls through application Pin
Innayat Ullah8-Nov-09 18:47
Innayat Ullah8-Nov-09 18:47 
Questionssssssssssssssssssssss Pin
zhuangkai3-Nov-09 23:08
zhuangkai3-Nov-09 23:08 
AnswerRe: ssssssssssssssssssssss Pin
padmanabhan N3-Nov-09 23:11
padmanabhan N3-Nov-09 23:11 
GeneralRe: ssssssssssssssssssssss Pin
OriginalGriff4-Nov-09 1:19
mveOriginalGriff4-Nov-09 1:19 
GeneralRe: ssssssssssssssssssssss Pin
padmanabhan N4-Nov-09 1:32
padmanabhan N4-Nov-09 1:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.