我會考慮使用排序plugin
架構的,因爲這是你的應用程序自身的整體設計。
您可以通過執行類似下面的完成這一基本(注意,這個例子使用StructureMap
- 這裏是一個鏈接到StructureMap Documentation):
創建的界面,您DbContext
對象可以派生。
public interface IPluginContext {
IDictionary<String, DbSet> DataSets { get; }
}
在你的依賴注入建立(使用StructureMap) - 這樣做如下:
Scan(s => {
s.AssembliesFromApplicationBaseDirectory();
s.AddAllTypesOf<IPluginContext>();
s.WithDefaultConventions();
});
For<IEnumerable<IPluginContext>>().Use(x =>
x.GetAllInstances<IPluginContext>()
);
對於每一個插件,或者改變{plugin}.Context.tt
文件 - 或添加partial class
導致生成DbContext
的文件從IPluginContext
派生。
public partial class FooContext : IPluginContext { }
改變{plugin}.Context.tt
文件爲每個插件揭露類似:
public IDictionary<String, DbSet> DataSets {
get {
// Here is where you would have the .tt file output a reference
// to each property, keyed on its property name as the Key -
// in the form of an IDictionary.
}
}
現在,您可以像下面這樣:
// This could be inside a service class, your main Data Context, or wherever
// else it becomes convenient to call.
public DbSet DataSet(String name) {
var plugins = ObjectFactory.GetInstance<IEnumerable<IPluginContext>>();
var dataSet = plugins.FirstOrDefault(p =>
p.DataSets.Any(ds => ds.Key.Equals(name))
);
return dataSet;
}
原諒我,如果語法並不完美 - 我在帖子中這樣做,而不是在編譯器中。
最終的結果讓您可以靈活地做一些事情,如:
// Inside an MVC controller...
public JsonResult GetPluginByTypeName(String typeName) {
var dataSet = container.DataSet(typeName);
if (dataSet != null) {
return Json(dataSet.Select());
} else {
return Json("Unable to locate that object type.");
}
}
顯然,在長期的 - 你想控制將被倒置,這裏的插件實際上是一個綁定到架構中,而不是服務器期待的類型。您可以使用完成這種延遲加載的這樣的事情,但是 - 其中主要的應用暴露了一個終點,所有的插件領帶來。
這將是這樣的:
public interface IPlugin : IDisposable {
void EnsureDatabase();
void Initialize();
}
您現在可以公開此接口的任何應用程序開發誰想要爲你的架構(DNN風格)創建的插件 - 和你的StructureMap
配置工作是這樣的:
Scan(s => {
s.AssembliesFromApplicationBaseDirectory(); // Upload all plugin DLLs here
// NOTE: Remember that this gives people access to your system!!!
// Given what you are developing, though, I am assuming you
// already get that.
s.AddAllTypesOf<IPlugin>();
s.WithDefaultConventions();
});
For<IEnumerable<IPlugin>>().Use(x => x.GetAllInstances<IPlugin>());
現在,當你初始化應用程序,你可以這樣做:
// Global.asax
public static IEnumerable<IPlugin> plugins =
ObjectFactory.GetInstance<IEnumerable<IPlugin>>();
public void Application_Start() {
foreach(IPlugin plugin in plugins) {
plugin.EnsureDatabase();
plugin.Initialize();
}
}
您的每個IPlugin
對象現在都可以包含其自己的數據庫上下文,管理安裝(如果需要)其自己的數據庫實例/表的過程,並優雅地處置其自身。
很明顯,這不是一個完整的解決方案 - 但我希望它能讓你在有用的方向開始。 :)如果我可以幫助澄清此處的任何內容,請讓我知道。