Reflection-based injection vs. dynamic proxy: Practical considerations?
I'm working on some framework-ish code designed to execute a huge number of operations (hundreds of thousands), all of which use the same basic components, but need to accept operation-specific configuration data from an external source.
Assume for the moment that there's a configuration repository which, given the appropriate list of setting names, knows how to load these settings efficiently and store them in a type like the following:
public interface IConfiguration
{
dynamic Get(string key);
void Set(string key, dynamic value);
}
What I'm planning to do is implement either some fluent mapping syntax or just decorate the component classes with attributes like so:
public class MyComponent : IActivity
{
[Configuration("Threshold")]
public virtual int Threshold { get; set; }
[Configuration("SomeKey", Persistence = ConfigPersistence.Save)]
public virtual string SomeSetting { get; set; }
}
You get the picture... hopefully. What's important to note is that some properties actually need to be saved back to the repository, so conventional DI libraries don't work here; and even if they did, they're blunt instruments not designed to be spinning up hundreds of thou开发者_StackOverflowsands of components and loading/saving millions of attributes. In other words, I don't think I'm reinventing the wheel, but if somebody wants to try to convince me otherwise, feel free.
Anyway, I'm considering two possible options to handle the "injection" of configuration data into these component instances:
Plain vanilla Reflection - scan the type for configuration attributes and save the member info (along with the config key) in a static dictionary. Then use reflection methods such as
PropertyInfo.SetValue
andPropertyInfo.GetValue
for the injection and extraction (for lack of a better term). This is similar to the approach used by most DI libraries.Use a dynamic proxy such as Castle and hook up an interceptor to the decorated properties, such that instead of referencing private/autogenerated fields, they reference the
IConfiguration
instance (i.e. theget
method callsIConfiguration.Get
and theset
method callsIConfiguration.Set
). This is similar to the approach used by NHibernate and other ORMs.
The full implementation may end up being a fair amount of work, so I don't want to go too far down the wrong path before realizing I missed something.
So my question is, what are the pros/cons of either approach, and what are the pitfalls I need to avoid? I'm thinking in broad terms of performance, maintainability, idiot-proofing, etc.
Or, alternatively, are there other, quicker paths to this goal, preferably which don't have steep learning curves?
Dynamic proxy is much better approach. Define a "configuration" interceptor that injects the value from the configuration into your component (preferably lazily). Using Dynamic proxy, I'd also implement a generic IDisposable interface to your proxied Component, so that when the object is disposed or GC'd, it will persist configuration values based on the Peristence flag set in your attribute.
精彩评论