Шаблон подход
В соответствии с вашими потребностями, я предлагаю вам использовать шаблон вместо того чтобы развивать свой собственный продюсер, потому что, среди прочего, причины развертывания. Используя производителя шаблонов (поставляется с CodeFluent Entities), вы можете быстро и легко создавать сложные скрипты, используя метамодель CodeFluent Entities.
Этот производитель основан на движке шаблонов CodeFluent Entities и позволяет создавать текстовые файлы (JavaScript в вашем случае) во время производства. Напоминаем, что шаблон - это просто смесь текстовых блоков и логики управления, которые могут генерировать выходной файл.
Этот производитель занимается всеми распространенными операциями: обновите проект (.XXproj), чтобы добавить ваши сгенерированные файлы, добавить отсутствующие ссылки и т. д. После этого вы можете найти пример создания файла сценария IndexDB на основе модели CodeFluent Entities (только демонстрационные цели). Вот исходный файл шаблона:
[%@ reference name="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll" %]
[%@ namespace name="System" %]
[%@ namespace name="System.Linq" %]
[%@ namespace name="CodeFluent.Model" %]
var context = {};
context.indexedDB = {};
context.indexedDB.db = null;
context.indexedDB.open = function() {
var version = 11;
var request = indexedDB.open([%=Producer.Project.DefaultNamespace%], version);
request.onupgradeneeded = function (e) {
var db = e.target.result;
e.target.transaction.onerror = context.indexedDB.onerror;
[%foreach(Entity entity in Producer.Project.Entities){
string properties = String.Join(", ", entity.Properties.Where(p => !p.IsPersistenceIdentity).Select(p => "\"" + p.Name + "\""));
%]
if (db.objectStoreNames.contains("[%=entity.Name%]")) {
db.deleteObjectStore("[%=entity.Name%]");
}
var store = db.createObjectStore("[%=entity.Name%]",
{ keyPath: "id", autoIncrement: true });
store.createIndex([%=properties %], { unique: false });[%}%]
};
request.onsuccess = function (e) {
context.indexedDB.db = e.target.result;
};
request.onerror = context.indexedDB.onerror;
};
[%foreach(Entity entity in Producer.Project.Entities){
string parameters = String.Join(", ", entity.Properties.Where(p => !p.IsPersistenceIdentity).Select(p => p.Name));%]
context.indexedDB.[%=entity.Name%] = {}
context.indexedDB.[%=entity.Name%].add = function ([%= parameters %]) {
var db = context.indexedDB.db;
var trans = db.transaction(["[%=entity.Name%]"], "readwrite");
var store = trans.objectStore("[%=entity.Name%]");
var request = store.put({
[%
foreach (Property property in entity.Properties.Where(p => !p.IsPersistenceIdentity)) {%]
"[%=property.Name%]": [%=property.Name%], [%}%]
"timeStamp": new Date().getTime()
});
request.onsuccess = function (e) {
console.log(e.value);
};
request.onerror = function (e) {
console.log(e.value);
};
};
context.indexedDB.[%=entity.Name%].delete = function (id) {
var db = context.indexedDB.db;
var trans = db.transaction(["[%=entity.Name%]"], "readwrite");
var store = trans.objectStore("[%=entity.Name%]");
var request = store.delete(id);
request.onsuccess = function (e) {
console.log(e);
};
request.onerror = function (e) {
console.log(e);
};
};
context.indexedDB.[%=entity.Name%].loadAll = function() {
var db = context.indexedDB.db;
var trans = db.transaction(["[%=entity.Name%]"], "readwrite");
var store = trans.objectStore("[%=entity.Name%]");
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
request.onsuccess = function (e) {
// not implemented
};
request.onerror = function (e) {
console.log(e);
};
};
[%}%]
function init() {
context.indexedDB.open(); // initialize the IndexDB context.
}
window.addEventListener("DOMContentLoaded", init, false);
Затем вам нужно настроить Entities проекта CodeFluent путем добавления шаблона Producer и определить шаблон выше в качестве исходного файла.
Если учесть следующую модель:
Просто построить его для создания файла сценария IndexDB в целевом проекте (веб-приложение, например), и вы будете иметь возможность манипулировать генерируемый API, как это:
context.indexedDB.Contact.add("Peter", "Boby")
context.indexedDB.Product.add("Tablet")
context.indexedDB.Product.add("Computer")
context.indexedDB.Contact.delete(1)
context.indexedDB.Product.loadAll()
подход на заказ Производитель
тем не менее, если когда-нибудь вы должны быть ориентированы на ехнологии или платформа, которая не поддерживается CodeFluent Entities изначально, вы можете создать свой собственный производитель, реализуя интерфейс IProducer:
public interface IProducer
{
event Producer.OnProductionEventHandler Production;
void Initialize(Project project, Producer producer);
void Produce();
void Terminate();
}
Прежде всего, вы должны понять, что CodeFluent Entitie сборки двигателя вызывает каждый из ваши настроенные производители по очереди генерируют ваш код.
Во-первых, CodeFluent Entities вызывает метод Initialize
для каждого производителя. В качестве параметра в качестве параметра используется экземпляр проекта CodeFluent Entities и текущего производителя. Затем он вызывает метод Product
, следуя тому же процессу. Это правильное место для реализации вашей логики генерации. Наконец, вы можете реализовать логику завершения в методе Terminate
.
CodeFluent предоставляет некоторые базовые классы, которые реализуют интерфейс IProducer, такие как BaseProducer, который находится в сборке CodeFluent.Producers.CodeDom, что обеспечивает поведение как «добавить недостающие ссылки» или «обновить проект Visual Studio (.XXproj).
Кроме того, вот blog post, который может помочь вам интегрировать пользовательские производителя к модельера.
Суб-Producer подход
Другим подходом может стать разработка custom Sub-Producer, но, на мой взгляд, не подходит к вашим потребностям.