Copperfield is an extensibility framework built around contextual awareness. It is intended to be used in combination with one's DI / IoC framework of choice.
Copperfield is an extensibility framework that resolves dependencies based on the current runtime context of an application or user session. It is meant to be used in conjunction with your Dependency Injection / Inversion of Control framework of choice. Currently
fluent configuration support is included for StructureMap however the goal is for Copperfield to be agnostic to the DI/IoC employed.
While Copperfield does rely heavily upon reflection for its initial wiring there is a significant focus on enterprise scalability. Our goal is to have 100% caching of all type-based reflection methods. In addition, costly anonymous methods are compiled to functions
in memory during runtime - these compiled and cached delegates are reused whenever possible.
While the framework has seen limited used in demo and sandbox applications the hope is to prepare for more wide-spread implementation. We feel that a truly useful and robust framework can never be developed in isolation; we hope that through community involvement
and contribution that Copperfield can be made even more flexible and beneficial.
Nuts & Bolts
The Copperfield framework must first be integrated with your DI/IoC framework of choice. This is a fairly painless process if you are using StructureMap - a fluent API can enable the framework in just two lines of code, or you can configure Copperfield using
it's internal fluent API with a few more lines of code and gain some additional configuration options. If you are using a different IoC framework (e.g. Castle Windsor or Autofac) then you can either use Copperfield's API to configure the framework
during initial bootstrapping, or you can leverage Copperfield's API to create your own streamlined implementation classes.
Part of the configuration process is to define a Context
class, as well as an implementation of a
The Context class normally contains simple, discrete properties that describe the state of an application. Enum types are ideal for this, though strings and other data types can also be used.
The Context Manager has two important responsibilities. Its first responsibility is to provide an instance of the Context to your application code and to take an updated instance of the Context class in to memory. Your application should update the property
values within the Context class as your application context changes over the course of the session. Its second responsibility is to provide the Context class and its values in a meaningful way to the framework during application runtime. The framework will
use the application's context to provide appropriate runtime instances to your IoC framework.
Framework-provided attributes define what types are pluggable through the framework, as well as which, and under what conditions, each concrete type will be provided. During application initialization, Copperfield will scan your assemblies for types decorated
by these attributes and will then add them to its own internal object graph. It uses this object graph to then provide appropriate concrete types when needed.
Many IoC frameworks have some level of support for this included out-of-the-box (e.g., StructureMap's x.For<IFoo>().ConditionallyUse(c => ...)). The Copperfield framework improves upon this approach in several key ways, however:
Current Development Backlog (Not All-Inclusive)
- Eliminates messy and difficult to read configuration code from your bootstrapper class(es)
- Allows developers to easily see how and when concrete types will be used, from those concrete classes themselves (no more referring back to your boostrapper!)
- Allows context-based dependency resolution to be easily enabled and disabled via your boostrapper
- Create documentation and guidance files
- Increase code coverage
- Better define permitted context property types
- Further vet context attribute design
- Assess viability for collections and enumerable types
- Assess performance and ease of implementation in more diverse use cases