Extracting Class Objects from Entity Framework - domain-driven-design

I have just started to investigate Microsoft's Entity Framework (EF) with a view to replacing our existing Linq2Sql data access library.
Whilst following some of the sample projects I came across the 'Add Code Generation Item' (context menu on the designer surface), specifically the 'EF 5.x DbContext Generator' template.
This template generates some nice simple (POCO) class objects for the model.
In my overall structure, I would like to extract/move these classes into a different project/assembly so that I can reference them from a generic repository i.e. I want to decouple the application's Data Access Layer from the EF entity data model.
Is this possible, or do I need to manually create a map for each class object (e.g. .ToDomainModel(), .FromDomainModel()).
Apologies if this is a stupid question - in my defence I am new to EF and also still getting to grips with the concept of the Data Driven Domain.

It is possible but you will lose part of the auto-magic. The auto-generated item is a T4 template. If you open it you will find somewhere at the beginning relative path to .edmx file. If you move the template you just need to update the path accordingly to point to the .edmx file you want to use for generation.
The disadvantage is that moving the template elsewhere will break automatic class regeneration when the .edmx file is saved (but I didn't searched for the solution so maybe it is possible to make it work). Because of that you must manually run custom tool (item in .tt file context menu) after each saved change to EDMX file.

Related

Duplicate files in DerivedData folder using CoreData generator

I'm trying to generate NSManagedModels from my datamodel. Generation works but after I got many errors :
error: filename "Station+CoreDataProperties.swift" used twice:
'/Users/Me/MyApp/Models/CoreData/Station+CoreDataProperties.swift' and
'/Users/Me/Library/Developer/Xcode/DerivedData/MyApp-gwacspwrsnabomertjnqfbuhjvwc/Build/Intermediates/MyApp.build/Debug-iphoneos/MyApp.build/DerivedSources/CoreDataGenerated/Model/Station+CoreDataProperties.swift'
:0: note: filenames are used to distinguish private
declarations with the same name
I try clean build folder and derivedData directory hard delete. I'm using Xcode 8 BETA maybe it's a bug ?
I get this in Xcode 8.1
For me following steps solved the issue. Please note that order matters.
1) Create entity in Core Data model.
2) Under class section, make settings as on following image.
Module: Current Product Name
Codegen: Manual/None
3) Generate your NSManagedObject subclass.
This post greatly helped me solve this problem myself. Personally I look at this as an Xcode bug. Bug or not this is a huge chicken and egg situation.
I ran into this by:
Created a new Project using Core Data
Generated my NSManagedObject subclass+extension (while codegen: ClassDefinition)
I accidentally saved the generated classes in the Wrong folder
I deleted the generated files
Re-generated in folder I wanted
đź’Ą- Xcode used twice errors
As others have posted I kept cleaning my build (and clean build folder) but that never fixed the build issue.
I finally figured out if you originally created your NSManagedObject generated classes with codegen: ClassDefinition, as I did without knowing then you are locked in for the chicken and egg issue.
I then deleted the auto generated classes thinking I had to re-generate, so I did. Once re-generated I would get the used twice build error again. I manually went into the ../DerivedSources/CoreDataGenerated/Model/.. and deleted the duplicates. Again, I re-generated thinking I'd only have 1 copy (in my project) but I was wrong. If codegen: ClassDefinition was originally set then Xcode will keep creating the auto-generated classes+extensions and put them in the buried folder ../DerivedSources/CoreDataGenerated/Model/... I repeated this chicken and egg a few times before catching on.
I later realized you do indeed need to mark codegen: Manual/None however to get things back in sync you need to delete the auto-generated files in ../DerivedSources/CoreDataGenerated/Model/.. and in your project if you have any there still.
Be careful setting codegen: Manual/None, for me it was bit tricky because codegen: Manual/None wouldn't stick. I had to click back and forth between entities multiple times to double/triple check each entity was set to codegen: Manual/None. Then auto generate the files. At this point your only copy of the auto generated files should be in your project and not in ../DerivedSources/CoreDataGenerated/Model/...
Last, I think this is a bug because if you specify codegen: Manual/None I don't expect Xcode to auto generate files at all, yet it does and puts them in your project. More confusing if your setting is codegen: ClassDefinition, who the heck knows Xcode will put the files in a buried directory yet it is available for use in your project. My beef with this is the auto generated files aren't source controlled and if I change computer I have to know to auto-generate them on the new station.
Hope this helps someone else!
Cheers!
This is indeed not a bug. As #Morrowless suggests both class definition and properties extension are created. If this is not wanted, select Manual/None under Codegen before generating the code. If the code is already generated, just delete them, and try Editor->Create NSManagedObject Subclass... again from the menu (after setting Manual/None).
Note, in the picture below, the Class Name 'Contact' is specific to my project. You will see your entity name instead.
If you generated CoreData subclasses with codegen: ClassDefinition your basically screwed. The only way to fix it is to:
Delete your CoreData subclasses.
Delete your derived data folder.
Clean your project (CMD+K).
Generate new CoreData subclasses, this time select Codegen: Manual/None and Module: Current Product Module
This is not a bug. Codegen generates these files in the DerivedData folder, so you don't need to create them again in your project, hence the compile error.
From Xcode 8.0 Release notes:
Xcode automatically generates classes or class extensions for the entities and properties in a Core Data data model. Automatic code generation is enabled and disabled on an entity by entity basis, and is enabled for all entities in new models that use the Xcode 8 file format. This feature is available for any data model that has been upgraded to the Xcode 8 format. You specify whether Xcode generates Swift or Objective-C code for a data model using the data model’s file inspector.
When automatic code generation is enabled for an entity, Xcode creates
either a class or class extension for the entity as specified in the
entity's inspector: the specified class name is used and the sources
are placed in the project’s Derived Data. For both Swift and
Objective-C, these classes are directly usable from the project’s
code. For Objective-C, an additional header file is created for all
generated entities in your model. The header file name conforms to the
naming convention “DataModelName+CoreDataModel.h”.
However, if you selected Category/Extension under the codegen pulldown menu in the data model inspector (because you want to add logic to your model): codegen will wrongly generate both the class definition and properties extension.
The solution is to simply delete the properties extension (ClassName+CoreDataProperties.swift). Your project should now compile.
After following the guidance from oyalhi and Vladimir Shutyuk, (deleting the NSManagedObject files, changing the entity codegen to Manual/None), I had to restart Xcode to allow it to index again before I could re-generate the NSManagedObject files and get a successful compile.
For the sake of completeness..:
I just ran into the same error, but none of the proposed solutions worked. What puzzled me was that even switching from automated code generation to manual for the one (as I thought) problematic entity didn't do anything.
Finally, I figured out that I had several entities with the same name, but they all shared the same classname. The reason for this was that I copy&pasted one entity several times to save me some work, because they also have a few attributes in common.
Turns out XCode renames the duplicates by adding 1, 2,... to the entity name, but leaves the class name as before. And since now entity name and class name are "unrelated", renaming the entity won't change the class name either.
Hope it helps someone - I have also filed a bug report for this.

XPages: Is there a way to copy/rename custom controls

In Lotuscript you can manipulate design elements - create them, change them, rename them, etc.
Are you able to do the same thing for Xpages and custom controls design elements?
====================================================================
My question should have been clearer. What I want to accomplish is to copy an existing cc and give it a new name, programatically. The app will then close and reopen (or refresh or get rebuilt) so that the app can "see" the new cc. If I copy the cc it will only have one field on it. I will add custom code later. I could just create a new cc with no code in it, that would work too.
I am not familiar with the DXL exporter but I can research it. Using that can I just export the design of the cc to an XML file in a temp directory, use the transform to change the name, and then import the control?
I think the XPage or Custom Control design elements are probably under MISC_CODE or MISC_FORMAT design elements in a NoteCollection.
However, accessing that design element is the easy part. Doing a create / rename / change etc is a much bigger task.
Remember that the XPage or Custom Control XML file is only a starting point:
XPages and Custom Controls also have a .xsp.metadata file, as you'll see with source control.
Custom Controls will also have (and need) a .xsp-config file.
There are corresponding .java files for every XPage and Custom Control in the Local source folder. They're created by a builder based on parsing the XML. I don't think you'll be able to create those programmatically. I'm not sure of the impact of renaming them.
For Custom Controls, even if you can rename the .java file, it's referenced in the .java files of relevant XPages. Updating those is goiong to be a significant task.
The XPages runtime doesn't even use those .java files. Instead it uses the .class files in WebContent\WEB-INF (you need to use Project Explorer view and modify the filter to see those files). This is compiled byte code, so you won't be able to update the .class files for XPages containing renamed Custom Controls, as far as I know.
Even if you can rename the .class files, the XPages runtime almost certainly won't use them until either a Clean (which will overwrite anything you've done) or an HTTP restart. As far as I can tell they're cached.
Depending on your use cases, it's possible not all these points will be an issue, e.g. if you're modifying the XML files and building with headless designer.
I suspect this is why nothing was added to the NoteCollection object or a specific NotesXPage / NotesCustomControl API class added.
In Lotuscript you can manipulate design elements - create them, change them, rename them, etc.
This is only partially true. There is a LS API to create/alter views and outlines. Good luck with other design elements - although they're standard "notes", so you can access their items, in most cases you won't compile them and there will be some problems with signatures (real experience with TeamStudio CIAO).
Your question has two points of view - do you want to alter design elements in design process or alter running application?
To help a designer you can go the way of Eclipse extensions and enrich tools in IBM Designer to help developer. Something like TeamStudio Designer. In this case you need to look for source design elements, mentioned by Paul.
To enrich application you don't need to alter source design elements. IBM Designer transforms XML in source code to a Java code (JSF framework) - so you can generate your Java code from anything you wish. Take a look inside Local\xsp folder of NSF in Package explorer. You will find Java sources made from your XPages and Custom Controls. So if you don't need to work with design elements, go for Java components - they can be built on the fly.
And of course, there is always the option of DXL framework - so you can clone/alter design of the application through XML transformations. Good starting point: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/ls-design-programming.htm

Flexible customization - Generating word document using C#

Problem - Generate a word document from information retrieved from database.
My solution - Create a word document template add fields/tags in places where values need to be inserted. The template will require tables and charts as well. Using document reflector that comes with open office xml sdk reflect on the document template and extract the w:document section and port it to C#. The rest of the logic revolves simply around finding the fields/tags, replacing them, etc. Very simple approach but not very flexible!
Challenge - I want the user to have the ability to customize the template or the generated document output. But this will not be possible if I embed the template logic in code.
Any other possibilities - I looked around at Templating using T4 and RazorEngine but could not find any concrete examples of how to create word documents using these two technologies.
Now what is the best approach?
I would really appreciate your inputs on what is the best and most flexible way to generate word documents using C#.
I'm actually working a project where the business users are designing word template with mail merge fields and we are populating the values using a 3rd party software package Aspose Words. http://www.aspose.com/categories/.net-components/aspose.words-for-.net/default.aspx
The software includes a library for merging data from datatables into the mail merge fields in the word document.
I also wrote a customized word task pane add in that retrieves data views from the database and lists the fields in a drag/drop interface that mimics a crystal or sql report writing interface.
Probably would of been easier to just use crystal or sql reporting though...
It's certainly possible to generate the contents of an Office doc using T4 or Razor and then package it up. The TestScribe powertool for Visual Studio Test Manager does just that with T4. There is a thread by Sally Cavanagh in the Q&A on this page http://visualstudiogallery.msdn.microsoft.com/e79e4a0f-f670-47c2-9b8a-3b6f664bf4ae that suggests a way to look at the T4 templates that it uses, which might get you jump-started.
Here is sample to play word document template with C#
You could use a content control databinding approach.
XML Mapping Task Pane for Word 2007/2010 is an authoring tool.
To create an instance document, you just attach your XML data file.
If the resulting documents will be opened in Word, that is all that is required: Word will bind the data itself. If your consuming application is not Word, you might want to resolve the bindings yourself (eg via Open XML SDK).
Content control databinding isn't intended to support repeats and conditionals. For a way to do that, look at my OpenDoPE convention
Take a look at Templater. Disclamer: I'm the author.
Check out JODReports or Docmosis. They are Java based but some of the templating features and output options might be ideal. You can call the command line interfaces unless they also have something better to reach from C#.

How can I customize the generated classes in SubSonic 2.2

I'm using SubSonic 2.2 for my DAL. To match the requirement, I need to customize some of classes which generated by SubSonic. For sample:
public partial class Category : ActiveRecord, IActiveRecord, IOtherInterface
Could you please give me some clues. Where I can modify the generated template? Thanks!
Jim is incorrect you can add an Interface via the partial class. I keep one folder with all of the Generated Files and another one with the Altered class files and I am adding an interface to the altered class files and it works just fine.
public partial class ContainerSearch : IContainerSearch
{
}
above is an example from my code I am using now
(edit: see runxc1's post for better answer)
You can modify the templates used to generate the class files to add in your other interface. You can't add an interface to the partial classes. The only trick is that this will add it to all generated classes. You can also just go into your automatically generated classes and add your interface manually after you generate the class files.
SubSonic 2.2 templates are a bit tricker to work with than the 3.0 templates, but it's still really easy to modify the templates.
See below links for info:
how to modify SubSonic 2.1 code generation
http://johnnycoder.com/blog/2008/06/09/custom-templates-with-subsonic/
Your options:
Modify templates used for generation to add in your interface (all classes), or
Modify templates used for generation to add in if/switches to only add interfaces to certain classes that match specific names, etc., or
Edit generated classes to add in your interface (must redo edits after each auto-generation)
After you modified those aspx files. Then you'll just need to update your .config file of your DAL to specify the new path to your customized aspx files and regen as usual.

Global Customized View for Document Libraries in Sharepoint

In Sharepoint document library, when we create a new document library, the default view is 'All Document'. This one:
We can make a custom view from View > Create View (at the upper right corner of document library view). I created a new standard view and named it 'Chromed View'. I edited it, then I saw that this view only applied on current document library:
The other document libraries cannot use this view.
I develop a system that triggers document library creation from CRM (the document library's view from CRM Iframe is using that chromed view). The creation itself went well, I can create document library using Sharepoint web services. But I still cannot apply a custom view automatically for that newly created doc lib.
My question is, can we make a view that is global (not in one document library only) so that we can use that global view for any document library.
Thanks b4 for any opinion :)
You could also create a new custom document library type, with the view embedded in it. Whenever a new library is created from the new doc lib type, it will get the new view.
This is still a not truly "global" view, and you may have the same problems if the view gets changed (the view won't be updated on document libraries that have been created with previous versions of the view).
One way to do this is to create a feature with an event receiver. When a user creates a list, you can check if the list is of the proper type (101), and then add new views to it. The feature could also add this view to existing document libraries on activation. Shouldn't be too much of an effort.
The view is not truly global. As list definitions are duplicated for each instance, there are no such thing as a global view (afaik) in WSS. We could all hope that views are a part of content type in the next version.
To globally change all document libraries and to change all existing libraries you need to edit the XSLT file that is in the XSL folder in layours/templates
There are a couple of them in there but these are how all the libraries are generated with this u can basically specify how a default"" library would look. Make sure to make a backup for these files though. Also creating a new content type and copying these xlts to a different file name and then linking your content type to these instead could also be a solution so when a user creates a new library using ur content type you can make sure that they are created in a way that you want.

Resources