Как правильно создать нового Producer?
-
21-12-2019 - |
Вопрос
Я использую инструмент управляемой объектной модели CodeFluentEntities для развертывания модели в механизме базы данных.
Я подумываю об использовании механизмов базы данных localStorage (например, IndexedDB или Web SQL) для хранения моих данных для веб-приложения без сервера.
Я заглянул в документация но мне кажется немного бедно...Я думаю, что понял основные принципы, такие как точки инъекции, которые Produce()
и Terminate()
а как насчет целевого каталога фактического производства?
В моем случае, то есть файлах исходного кода Javascript, как я могу правильно указать (ссылочным образом), где их генерировать?И должно ли это быть во внешнем проекте, или я могу просто заполнить каталог в другом проекте (например, .vsproj моего веб-приложения)?
Может ли документация включать образец кода, касающийся этих аспектов, или кто-то может перенаправить меня на статью, соответствующую моим потребностям?
Решение
Шаблонный подход
В соответствии с вашими потребностями я предлагаю вам использовать шаблон вместо разработки собственного Producer, среди прочего, по причинам развертывания.С помощью производителя шаблонов (поставляемого вместе с 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);
Затем вам необходимо настроить проект CodeFluent Entities, добавив Производитель шаблонов и определив приведенный выше шаблон в качестве исходного файла.
Если рассмотреть следующую модель:
Просто создайте его для создания файла сценария 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 Build вызывает каждого из настроенных вами производителей один за другим для генерации вашего кода.
Во-первых, CodeFluent Entities вызывает Initialize
метод для каждого производителя.В качестве параметра он принимает экземпляр проекта CodeFluent Entities и текущего производителя.Затем он вызывает Product
метод, следующий тому же процессу.Это подходящее место для реализации вашей логики генерации.Наконец, вы можете реализовать логику завершения в Terminate
метод.
CodeFluent предоставляет некоторые базовые классы, реализующие интерфейс IProducer, например BaseProducer, который находится в сборке CodeFluent.Producers.CodeDom и обеспечивает такое поведение, как «добавление недостающих ссылок» или «обновление проекта Visual Studio (.XXproj).
Кроме того, вот Сообщение блога это может помочь вам интегрировать собственного производителя в модельер.
Подход субпродюсера
Другой подход может заключаться в разработке индивидуальный суб-продюсер но, на мой взгляд, он не соответствует вашим потребностям.