I'm thinking of writing a domain specific language (DSL) to model business objects. The DSL will not be executed, instead it will be used by a template based code generator (probably CodeSmith) to generate the .NET & SQL.
The DSL will need to support the definition of the following elements:
Classes (name & description)
Properties (name, friendly name, type, null/not null)
Simple validation (required, regex, range, etc..)
Relationships between classes (1 to 1, 1 to many, many to many)
Inheritance (ok, maybe in version 2)
Here's a simple example of what the DSL code might look like:
Class: Insured
Desc: "Represents a person covered by an insurance policy"
Prop: FirstName, "First Name", String(20), not null
Prop: LastName, "Last Name", String(20), not null
Prop: MailAddress, "Mailing Address", Address, not null
Prop: SSN, "Social Security Number", String(9), null
Rule: RegEx, SSN, ^\d{9}$
Class: Address
Prop: Line1, "Line 1", String(30), not null
Prop: City, "City", String(30), not null
Prop: State, "State", String(2), not null
...
For the sake of keeping the DSL simple the more complex validation rules will be coded in the target language. The current plan is to make the generated code off limits and add the more complex rules to subclasses.
Has anyone written something similar to this? Can you provide any tips or links to similar solutions?
It's fairly easy to automatically convert the structure you present into XML. From there, I imagine it's possible to write some sort of transformation via XSLT or XQuery into whatever end result you desire. I wrote a Visual Studio add-in called CodeGenUtils to facilitate doing the transformations.
If you really feel like writing your own parser, I would suggest looking at existing textual DSL solutions such as, e.g., JetBrains MPS.
Suggest you take a look at OSLO, if only to avoid reinventing it.
I have a project called bdUnit where I used parts of the Oslo framework in creating a DSL that models user stories as C# interfaces and unit tests.
A portion of an example input:
begin story "AUserStory":
begin setup
#Person to have a ~Spouse(#Person)
~IsActive(true)
~Age(0)
~IsDead(false)
and several ~Children(#Person)
and a ~Location(#Location)
I want a #Person to be able to #Kill another #Person
I want a #Person to be able to #Marry another #Person
I want to be able to #Find all #Person
#Location to have a ~Latitude(0.0)
and a ~Longitude(0.0)
end setup
The corresponding generated C# code:
[PluginFamily("bdUnit")]
public interface IPerson
{
IPerson Spouse { get; set; }
bool IsActive { get; set; }
int Age { get; set; }
bool IsDead { get; set; }
IList<IPerson> Children { get; set; }
ILocation Location { get; set; }
void Kill(IPerson user);
void Marry(IPerson user);
void Find();
}
[PluginFamily("bdUnit")]
public interface ILocation
{
decimal Latitude { get; set; }
decimal Longitude { get; set; }
}
I compile the interfaces and tests in a dll so they are 'off-limits'. These interfaces can only be implemented in inheriting classes. I then use StructureMap to inject the required dependencies into the unit tests.
Hmm, it is from the Java world, however using Eclipse project TMF Xtext such a task will be done in minutes.
Check out their homepage, thei provide very similar example.
Related
I have a ASP.NET MVC4 application and am using Unity for IOC. I am using Unity.MVC4 and UnityConfiguration Nuget packages to help with the registration.
I need to automatically register a load of interfaces and their related types to the Unity container. To do this I created a dummy interface; IDependencyInjectionScanner that all my real interfaces inherit from. Below is the code showing that.
public interface IDependencyInjectionScanner
{
}
public interface IChair : IDependencyInjectionScanner
{
NumberOfLegs { get; set; }
}
public class Chair : IChair
{
public NumberOfLegs { get; set; }
}
public interface ITable : IDependencyInjectionScanner
{
NumberOfChairs { get; set; }
}
public class Table : ITable
{
public NumberOfChairs { get; set; }
}
I then used UnityConfiguration to bind the registrations using the scanner. I have get the interfaces being correctly resolved in the controller. Below is the code that shows how I did the binding.
Scan(scan =>
{
scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
scan.With<FirstInterfaceConvention>();
scan.Include(x => (x.GetInterface(typeof(IDependencyInjectionScanner).Name) != null));
scan.ForRegistries();
});
The problem is that I want to register all the types found by the scanner using the hierarchical lifetime manager but can figure out how to do this. The GitHub page for UnityConfiguration https://github.com/thedersen/UnityConfiguration states that this could be achieved by the code below:
Configure<IChair>().AsHierarchicalControlled();
However I if I have to do that for each of the interfaces bound by the scanner then the scanner is of no use as I may as well do:
Register<IChair, Chair>().AsHierarchicalControlled();
Can someone assist me with finding a solution to this please.
Here's an answer to your question using UnityConfiguration. You can create a custom convention to configure the lifetime. Just be careful because it looks like the calls within the Scan() method are order dependent.
public class HierarchicalLifetimeConvention : IAssemblyScannerConvention
{
public void Process(Type type, IUnityRegistry registry)
{
registry.Configure(type).AsHierarchicalControlled();
}
}
and then add that to your Scan() call...
Scan(scan =>
{
scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
scan.With<FirstInterfaceConvention>();
scan.With<HierarchicalLifetimeConvention>(); //<-- New convention
scan.Include(x => (x.GetInterface(typeof(IDependencyInjectionScanner).Name) != null));
scan.ForRegistries();
});
As suggested by #TylerOhlsen I used the built-in Registration by Convention feature of Unity 3.0. I have got it to add the registration mappings and they are using the hierarchical lifetime manager. below is the code for that
container.RegisterTypes(
AllClasses.FromLoadedAssemblies().Where(
t => t.GetInterface(typeof(IDependencyInjectionScanner).Name) != null),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Hierarchical);
There is one thing that is disturbing me; when I look at the registrations I have 4 (based on the example code above). 2 type mappings for the Chair type and 2 type mappings for the Table type.
Can anyone shed any light on why this is, as I was only expecting two mappings.
I am trying to implement what I thought was a simple scenario using an OData service provided by WCF Data services (using the OData V3 application/json;odata=verbose payload format, for now. I may use the JSON Light format in the future). The basic scenario goes like this:
I have two entities:
class Person
{
public int ID { get; set; }
public string Name { get; set; }
public virtual PersonCategory Category { get; set; }
}
class PersonCategory
{
public int ID { get; set; }
public string Description { get; set; }
public virtual ICollection<Person> People { get; set; }
}
Now, I want to create a simple edit page for a Person. This edit page might have an input for the Name, and an input or drop-down for the Category of the Person.
So, the scenario goes:
Code downloads the Person using $expand for the Category: GET /api.svc/People(1)?$expand=Category
User edits both the person's Name property and their Category.
Code for the page makes a single request to update that Person's Name and Category properties.
The key here is in "a single request". This is the part that I'm having trouble finding documentation for. I've seen examples where they split number 3 above into two requests. Something like this (I don't remember the exact format - I'm also not sure if you'd have to DELETE the Category link before doing the PUT):
PATCH /api.svc/People(1) with content: {"Name": "new name" }
PUT /api.svc/People(1)/$links/Category with content: { "url": "/api.svc/Categories(2)" }
But, I've also heard it said, but not demonstrated, that it's possible to implement this update as a single request with the change to the Category navigation property specified inline with the other changes to the Person entity. Could someone give me an example of how this might be done? Also, can you show me how it would be done with a many-to-many navigation property, as opposed to the one-to-many I've described above.
And finally, I'm currently using the verbose JSON format, V3. Would your answers to the questions above be different if I instead used the new JSON light format? If so, how?
I found two ways to represent navigation properties inline:
application/json;odata=verbose - { "Name": "new name", "Category": { "__metadata": { "uri": "Categories(2)" }}}
application/json - { "Name": "new name", "Category#odata.bind": "Categories(2)" }
Pratik's comment was the answer (Pratik if you'd like to repost this as an answer, I'll mark it as such - thanks!):
Question: Do you want to update the category instance or do you want to update some of the properties of the category instance. There is no way to do the later other than batch. For the former, you can do something like: { "Name" : "new name", "Category" : { "__metadata" : { "uri" : "/api.svc/Categories(2)" }}}. Hope this helps. – Pratik
You don't need a batch, anymore. You can do it in one call. You simply need to also send up the changed properties and let the repository handle the changed properties.
public class Person
{
public string FirstName {get;set;}
public string LastName {get;set;}
public int Age {get;set;}
}
Let's say you notice the first name has a typo, Jhon and it is supposed to be John. You can edit the first name and send it up. So you have the following object model. You can get this in 1 of two ways:
Have two parameters and set BodyStyle = WebMessageBodyStyle.Wrapped
Just create a generic model object with two properties: Property one is of Type T and property 2 is a List.
So you would send up this json:
[{ FirstName = 'John' }, ['FirstName']]
Now on the server side, you can do what you need to do.
If you don't want to send the changed properties, you can guess the changed properties by choosing any property whose value isn't the default property.
{ FirstName = 'John' }
Then you can use a few methods to see what properties have changed:
Custom code per entity to make sure that each property is not the default value and set it. Requires a piece of code per entity.
Reflection to make sure that each property is not the default value. Requires 1 class for all entities. I did this back in 2014 here in Entity Framework: http://www.rhyous.com/2014/12/01/entityupdater-generic-helper-for-entity-framework/
I'm working on developing my first Data Driven Domain using Dependency Injection in ASP.net.
In my Data Access Layer if have created some domain data models, for example:
public class Company {
public Guid CompanyId { get; set; }
public string Name { get; set; }
}
public class Employee {
public Guid EmployeeId { get; set; }
public Guid CompanyId { get; set; }
public string Name { get; set; }
}
I have then developed an interface such as:
public interface ICompanyService {
IEnumerable<Model.Company> GetCompanies();
IEnumerable<Model.Employee> GetEmployees();
IEnumerable<Model.Employee> GetEmployees(Guid companyId);
}
In a separate module I have implemented this interface using Linq to Sql:
public class CompanyService : ICompanyService {
public IEnumerable<Model.Employee> GetEmployees();
{
return EmployeeDb
.OrderBy(e => e.Name)
.Select(e => e.ToDomainEntity())
.AsEnumerable();
}
}
Where ToDomainEntity() is implemented in the employee repository class as an extension method to the base entity class:
public Model.EmployeeToDomainEntity()
{
return new Model.Employee {
EmployeeId = this.EmployeeId,
CompanyId = this.CompanyId,
Name = this.Name
};
}
To this point, I have more or less followed the patterns as described in Mark Seeman's excellent book 'Dependency Injection in .NET' - and all works nicely.
I would like however to extend my basic models to also include key reference models, so the domain Employee class would become:
public class Employee {
public Guid EmployeeId { get; set; }
public Guid CompanyId { get; set; }
public Company { get; set; }
public string Name { get; set; }
}
and the ToDomainEntity() function would be extended to:
public Model.Employee ToDomainEntity()
{
return new Model.Employee {
EmployeeId = this.EmployeeId,
CompanyId = this.CompanyId,
Company = (this.Company == null) ? null : this.Company.ToDomainEntity()
Name = this.Name
};
}
I suspect that this might be 'bad practice' from a domain modelling point of view, but the problem I have encountered would also, I think, hold true if I were to develop a specific View Model to achieve the same purpose.
In essence, the problem I have run into is the speed/efficiency of populating the data models. If I use the ToDomainEntity() approach described above, Linq to Sql creates a separate SQL call to retrieve the data for each Employee's Company record. This, as you would expect, increases the time taken to evaluate the SQL expression quite considerably (from around 100ms to 7 seconds on our test database), particularly if the data tree is complex (as separate SQL calls are made to populate each node/sub-node of the tree).
If I create the data model 'inline...
public IEnumerable<Model.Employee> GetEmployees();
{
return EmployeeDb
.OrderBy(e => e.Name)
.Select(e => new Model.Employee {
EmployeeId = e.EmployeeId,
/* Other field mappings */
Company = new Model.Company {
CompanyId = e.Company.CompanyId,
/* Other field mappings */
}
}).AsEnumerable();
}
Linq to SQL produces a nice, tight SQL statement that natively uses the 'inner join' method to associate the Company with the Employee.
I have two questions:
1) Is it considered 'bad practice' to reference associated data classes from within a domain class object?
2) If this is the case, and a specific View Model is created for the purpose, what is the right way of populating the model using without having to resort to creating inline assignment blocks to build the expression tree?
Any help/advice would be much appreciated.
The problem is caused by having both data layer entities and domain layer entities and needing a mapping between the two. Although you can get this to work, this makes everything very complex, as you are already experiencing. You are making mappings between data and domain, and will soon add many more mappings for these same entities, because of performance reasons and because other business logic and presentation logic will need different data.
The only real solution is to ditch your data entities and create POCO model objects that can directly be serialized to your backend store (SQL server).
POCO entities is something that is supported in LINQ to SQL from day one, but I think it would be better to migrate to Entity Framework Code First.
When doing this, you can expose IQueryable<T> interfaces from your repositories (you currently called your repository ICompanyService, but a better name would be ICompanyRepository). This allows you to do efficient LINQ queries. When querying directly over a query provider you can prevent loading complete entities. For instance:
from employee in this.repository.GetEmployees()
where employee.Company.Name.StartWith(searchString)
select new
{
employee.Name,
employee.Company.Location
};
When working with IQueryable<T>, LINQ to SQL and Entity Framework will translate this to a very efficient SQL query that only returns the employe name and company location from the database with filtering inside the database (compared to do filtering in your .NET application when GetEmployees() returns an IEnumerable<T>).
You can ask Linq2Sql to preload certain entities (as opposed to lazy load them) using DataLoadOptions.LoadWith method see: http://msdn.microsoft.com/en-us/library/bb534268.aspx.
If you do this with the Company entity then I think Linq2Sql won't have to reach to the database to fetch it again.
I created and love my Asp.Net MVC2 application. It's a very nice DDD app with Domain Model classes, View Model classes, a repository, and Json action methods to expose data.
My coworker wants to share my data with his Asp.Net Forms based C# code. He wants to pull through the Internet a class definition (like a Data Contract), then fill it with my Json results, effectively using something like a remote repository.
Any links or ideas on how to provide him with data contracts and data?
Darin Dimitrov had an excellent idea of consuming JSON data using data contracts here. Just wondering if it's possible to use MVC as the source for these items, then let him create the objects on his side, filled with data from my side.
The key to this question is how to send him my data classes, then send him my data.
class Program
{
[DataContract]
class Person
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "surname")]
public string Surname { get; set; }
[DataMember(Name="age")]
public int Age { get; set; }
}
static void Main(string[] args)
{
var json = #"{""name"" : ""michael"", ""surname"" : ""brown"", ""age"" : ""35""}";
var serializer = new DataContractJsonSerializer(typeof(Person));
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var person = (Person)serializer.ReadObject(stream);
Console.WriteLine("Name : {0}, Surname : {1}, Age : {2}",
person.Name, person.Surname, person.Age);
}
}
}
Write an OData service. The format is JSON, but the tools to consume it easily -- from many languages -- are already written for you.
The nice thing about this is that your data is now not only consumable by your JS and your friend's ASP.NET app, it's consumable by Excel, PHP, etc.
I have an abstract base class for audit properties. For brevity say it has one property
Public MustInherit Class AbstractAuditableEntity
...
Public Property CreatedTime() As DateTimeOffset
...
End Class
And then my auditable domain objects inherit from this class
Public Class Source
Inherits AbstractAuditableEntity
...
Public Property SourceId() As String
...
End Class
I have the following table DDL to which I want to map my domain object "Source". Essentially the relationship between each (concrete) domain object and table is 1-1, with each table having the required audit column.
CREATE TABLE Source
(
SourceID VARCHAR(10) NOT NULL,
CreatedTime DATETIMEOFFSET(3) NOT NULL,
CONSTRAINT PK_Source PRIMARY KEY (SourceID))
GO
Using an external mapping file my first attempt to map the class to the table would foolishly be:
<?xml version="1.0" encoding="utf-8"?>
<Database Name="" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
<Table Name="Source" Member="Sources">
<Type Name ="Source">
<Column Name="SourceID" Member="SourceID" IsPrimaryKey="true" CanBeNull="false"/>
<Column Name="CreatedTime" Member="CreatedTime" />
</Type>
</Table>
</Database>
However this generates the following exception:
The column or association 'CreatedTime' in the mapping had no corresponding member in type 'Source'. Mapping members from above root type is not supported.
Within the context of my persistence layer I am not trying to represent an inheritance hierarchy as such, but within the context of my application I am simply using a base class to provided properties required by all my domain objects. With a lot of fiddling with my mapping file (including mapping the audit columns to the base AbstractAuditableEntity type) and reading around, I am unable to achieve what I perceive as quite a straighforward ORM task.
Any thoughts or suggestions would be most welcome!
Thanks
I'm guessing that you are trying to emulate auditing fields like Ruby on Rails updated_on, created_on. If so, here is how I accomplished something similar using this post as a starting point
http://weblogs.asp.net/stevesheldon/archive/2008/02/23/a-method-to-handle-audit-fields-using-linq-to-sql.aspx
I implemented an interface in the Models namespace like so:
public interface IAuditable
{
DateTime CreatedOn { get; set; }
string CreatedBy { get; set; }
DateTime? ChangedOn { get; set; }
string ChangedBy { get; set; }
}
And then extended the partial classes of the data entities that had these fields:
public partial class DataModelIWantToAudit : IAuditable
{
}
And then overrode SubmitChanges on the DataContext to check for the implementation of the interface with the magic of Linq OfType<>:
public override void SubmitChanges(ConflictMode failureMode)
{
//Updates
foreach (var updatedModel in GetChangeSet().Updates.OfType<IAuditable>())
{
updatedModel.ChangedOn = DateTime.Now;
updatedModel.ChangedBy = Membership.GetUser().UserName;
}
//Inserts
foreach (var insertedModel in GetChangeSet().Inserts.OfType<IAuditable>())
{
insertedModel.CreatedOn = DateTime.Now;
insertedModel.CreatedBy = Membership.GetUser().UserName;
}
base.SubmitChanges(failureMode);
}
Hope that helps!
-Kelly
Kelly showed a great sample of how to do it - but you've basically hit one of the limitations of Linq-to-SQL.
It works great if you database table map more or less 1:1 to your domain objects. But it's weak and causes a lot of extra work once this is no longer the case.
In such a case, as soon as you have domain object inheritance and other things that need to be mapped to database tables, you're best bet would be to check out ADO.NET Entity Framework instead. The EF is specifically designed to handle these things - if you ever think "I need to map my objects ......" then you should think EF! :-)
Granted, the current EF shipping in .NET 3.5 SP1 has its warts and annoyances, but the EF 4 that is part of the .NET 4.0 wave (which should ship before the end of this year 2009), should solve a great many of those warts!
Check out the ADO.NET Entity Framework team blog for some teasers of what EF4 will bring us all!
Marc