Given these functional requirements:
User Management
Administrator
Librarian
Borrower
*The users have the option of logging-in via OpenID.
Property Management
Book
Memorandum
Circular
License
Normally, I would implement these in Java as:
interface User {}
class Librarian implements User {}
class Administrator implements User {}
class Borrower implements User {}
class OpenID {} //all Users HAS AN OpenID attribute (NULL if non-openId login)
interface Property{}
class Book implements Property{}
class Memorandum implements Property{}
class Circular implements Property{}
class License implements Property{}
But our project will use Groovy & Grails, which I haven't experience using yet. My question is,
how should the domain classes be designed based on the requirements above? I can't use an interface, and it seems inheritance is not a good practice. My idea is to use composition, though I'm quite bothered by the database tables that would be generated. What are the best practices in this situation?
Well first of all lets correct it, you can use inheritance in this case. You just need to change the convention of has a relationship to is a relationship.
Few factors to keep note of:
1. Grails works on convention over configuration.
2. You can use GORM which wraps the persistence layer and creates an Object Mapping for the underlying persistence layer with the help of Hibernate.
As per your functional requirement:-
If you do not want to have the User as part of persistence you can have an abstract class User which can hold the common properties of the User including the openId attribute. It has to be placed in src\groovy directory as per convention (since the base class is abstract, dependency injection will be defied)
The same goes for Property. Abstract Property class in src\groovy.
Now coming to the business models, extend each of the concrete entities (domain classes) from the abstract parent.
Summary:-
Create grails app
Under src\groovy(for example, I am considering a basic structure):
User.groovy:-
abstract class User{
String name
String emailId
OpenID openId
}
Property.groovy:-
abstract class Property{
String propertyName
}
Under grails-app/domain:
Librariran.groovy:-
class Librarian extends User{
//Attributes specific to Librariran
static constraints = {
}
static mapping = {
}
}
Book.groovy:-
class Book extends Property{
//Attributes specific to Book
static constraints = {
}
static mapping = {
}
}
So on and so forth. Groovy objects under grails-app/domain are considered concrete entities by Grails convention. More information you can obviously find here. You can also use composition if you come across scenarios, in fact I already mentioned that in User having OpenId.
Note:- This is context to latest version of Grails (> 2.x)
Related
i'm trying to build a class library for all of my mvc-5 projects. For that task i started with setting up some Abstract Classes for my DB Context and Indentity User like this
Public MustInherit Class ApplicationUserAbstract
Inherits IdentityUser
End Class
Public MustInherit Class DatabaseContextAbstract
Inherits DbContext
Public Property Users as DBSet(of ApplicationUserAbstract)
Sub New()
MyBase.New()
End Sub
Public Sub New(nameOrConnectionString As String)
MyBase.New(nameOrConnectionString)
End Sub
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
MyBase.OnModelCreating(modelBuilder)
End Sub
End Class
I think i have to get another approach to set DatabaseContextAbstract.Users to the correct Class inherting something like T of ApplicationUserAbstract. Any sugestions for that? I have no clue how to pass this to Users except Using something like
Public MustInherit Class DatabaseContextAbstract(of T as ApplicationUserAbstract)
Inherits DbContext
Public Property Users as DBSet(of T)
End Class
My next question: how would i access the current Instance of DatabaseContextAbstract in my abstract class? All approaches of DatabaseContextAbstract(of DatabaseContextAbstract(... would be nonsense...
EDIT:
The basic idea behind this is to pack Tables and Functions in that abstract Classes. e.g. There are the same UserRight and Group Tables behind every ApplicationUser in all of my projects. But every project may have project specific tables additionally to the base tables. There is still just one Application user in every project.
I don't see a whole lot of point to what you're doing here. IdentityUser is already abstract. It's intended that you're going to create a concrete class that inherits from it. If you perhaps intended to have multiple different types of users that all shared some subset of custom properties, I could see maybe adding an abstract subclass of IdentityUser that implements those, but you're not doing that here. However, even if you did, the user for Identity is a bit of a special case. You can only have one user table, so inheritance must start from a concrete base class, regardless. For example, the following will work fine:
public class ApplicationUser : IdentityUser {}
public class FooUser : ApplicationUser {}
public class BarUser : ApplicationUser
This will not work:
public abstract class ApplicationUserAbstract : IdentityUser {}
public class FooUser : ApplicationUserAbstract {}
public class BarUser : ApplicationUserAbstract {}
In the second scenario, FooUser and BarUser would get separate tables, which is not supported by Identity. In the first scenario, single-table inheritance will be utilized so FooUser and BarUser will be in the same table as ApplicationUser, with a discriminator column.
When it comes to your context, again, there's limited utility in having a base abstract context class. The context is inherently tied to a database, and it doesn't make sense to have multiple context each interacting with its own unique database that are all virtually carbon-copies. Even if you're dealing with a multi-tenant app, you only need one context. The individualization of the databases would be handled via the connection string, not which context class is utilized.
Finally, if you're using Identity, your context should inherit from IdentityDbContext, not DbContext. Among other things IdentityDbContext already contains a DbSet for users, so the one you added is unnecessary.
Long and short, none of this code does anything for an application. It's pointless abstraction for the sake of abstraction.
I was implementing repository decorator pattern on my project as:
[Auditable]
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
}
I got this idea from the following link.
https://efpatterns.codeplex.com/discussions/282699
But couldn't successfully implemented. Then I start learning about decorator pattern and DataAnnotation because the way Auditable attribute on Product entity is somewhat similar in DataAnnotation and decorator pattern. So my question is are they same thing.? If they are the same then how would I implement Auditable repository pattern (more on link) on my project.
That's not the decorator pattern as originally described by the Gang Of Four.
The decorator pattern is an inheritance technique to add functionality to existing classes. The pattern works by creating a set of subclasses which each provide a specific type of functionality on top of the base class.
Then you compose a combination by passing the existing instance as inner object to a subclass instance:
public class SecurityToken
public class ExpiringToken : SecurityToken;
public class RpcSecurityToken : SecurityToken;
So if you would like to have a token which is remote and will expire after an amount of time:
var token = new RpcSecurityToken(new ExpiringToken(new SecurityToken("sds")));
What you do is to just decorate a class with an attribute, which not is the same thing.
The decorator pattern is a mechanism of taking a base implementation of a given interface as extending its behavior without modification of original implementation.
Its similar to inheriting from a base class, however it has more flexibility. For example, a decorator class can be applied to any other class that implements the same interface, there is no restriction to only extending a single base class. They can also be chained together etc...
e.g
public interface IThing
{
void AMethod()
}
public abstract class ThingDecorator : IThing
{
private IThing inner;
public ThingDecorator(IThing inner)
{
this.inner = inner;
}
public virtual void AMethod()
{
this.inner.AMethod();
}
}
Inheriting from ThingDecorator and applying your own extension to the virtual AMethod will add behavior (decorate) the inner instance that is passed in. As the inner instance is coupled to an interface it can be any implementation of that interface.
In your example, you could inherit ThingDecorator as AuditThingDecorator, and override AMethod and include Audit features before you call the base.AMethod()
This is different to just applying an attribute to a class. I think you are trying to apply behavior with an attribute. Attributes can only apply behavior to the class if there is a container, or some other part of the system that can read them and actually apply given behavior. With DataAnnotations, there are other classes that read these attributes and apply behavior (for example, within ASP.NET MVC, the DefaultModelBinder use some of the attributes to provide validation when binding the model).
This is a AOP (apsect orientated programming) approach. One way to apply this (and a way I tend to use) is to use Castle.Core and create interceptors that can automatically implement interface methods or extend virtual methods and read attributes from the Methods/properties that are intercepting, and then apply behavior:
http://docs.castleproject.org/Tools.DynamicProxy-Introduction.ashx
They are both essentially proxies of a given type, however the Decorator pattern above is not dynamic, they are created within code, and the AOP approach can apply behavior at runtime.
I'm facing a issue regarding inheritance in Grails.
I have a domain class Person.grooy:
class Person{
String name
String contactNumber
Address address
}
Now I'm extending Person.groovy for Employee and Customer like:
class Employee extends Person{
String designation
}
class Customer extends Person{
String interest
}
Now I want separate table in my database for Employee and Customer having columns of Person i.e name,contactNumber and associate address key.
How could I achieve this. I searched every where but there is nothing for this aspect.
Is this one approach is not possible in GORM.
Please answer.
Thanks Guys
Finally I managed to get what I want just by placing a grails.persistence.Entity annotation to my child domain classes. I also make my parent i.e. Person.groovy abstract and place in src/groovy.
Now I have database hierarchy as I expected but some scaffold issues in controller still persist that will also sorted out with your help.
You need to disable table-per-hierarchy, which is by default enabled in Grails
class Employee extends Person{
String designation
static mapping = {
tablePerHierarchy false
}
}
table-per-hierarchy Ref
If you put your Person class in src/java or src/groovy it won't be mapped to the db.
Remember to import it into your Employee and Customer classes
import com.yourPackage.Person
class Employee extends Person{
}
It looks like inheritance is not the approach we need to follow here. You should create composition with Person class and it will store the properties of Person class in Employee.
class Employee {
Person person
String designation
static embedded = ['person']
}
Gorm Composition
you can put it inside src/java, but that solution will not be standard, as it really will not be treated as a grails domain example once you get deeper into the application.
For example, if you want to create a controller or a test script on the extended domain as per the previous answer, it will be complicated.
As of grails 2.2.x I believe, grails provides you with mapWith. You can use that for a more maintainable solution
class Employee{
static mapWith = "none"
}
My system consists of a back-end part, written in Java, exposing a set of web services which are defined contract-first using WSDL and XSD. Among the data transported over the web services are a large set of product types (they are different kinds of bank accounts, to be precise). Our front-end is a Grails web application. It uses and exposes the data and operations hosted by the back-end. The front-end has no database on its own for security reasons; all data is stored on the back-end. Pretty standard architecture.
Now, the set of products is large, growing, and volatile. Each product type has to be CRUD-ed on the web application user interface. It would be lovely if I could tell Grails to use the XSD specifications of the product types as domain types, and generate views and controllers for them.
I have not found a solution for this puzzle yet, even after extensive experiments and lots of web browsing. I have about a year's worth of professional experience with Grails. Any help or ideas would be appreciated.
Some details:
A product type is a simple POJO data carrier. Some simplified examples:
package jaxbgenerated;
public class Product1 {
protected Account from;
protected Account to;
protected String name;
// + getters and setters
}
public class Product2 {
protected List<Account> accounts;
protected String name;
// + getters and setters
}
public class Account {
protected String id1;
protected String id2;
// + getters and setters
}
Note that "Account" is not a product type but it is a JAXB-generated type. Products can contain such in addition to properties of simple data types like String, int and Date but they never contain other product types.
The end result I am aiming for is a Grails-generated form where a user can edit a Product1 instance with nested forms for editing its constituent Accounts. And likewise for Product2.
My idea is to first manually code a Grails domain class for each JAXB-generated type:
//in grails-app/domain:
import utilities.Copier
class Product1 extends jaxbgenerated.Product1 {
Product1(jaxbgenerated.Product1 jaxb) {
Copier.copy(jaxb, this)
}
static constraints = {
}
}
There is a bit of boilerplate code here but nothing more than I can live with. The Copier.copy() function is (I think) needed to convert a jaxbegenerated.Product instance fetched from the back-end to a Product1 instance which can be used in Grails. It recursively looks for jaxbgenerated properties in the jaxb source, and copies their values to the corresponding Grails domain type. The constructor is invoked from a layer that fetches data from the back-end.
I can use the constraints block to manually add semantic constraints where needed, e.g. that the "from" and "to" accounts are not the same.
Next, I generate controllers and views for all the Grails domain classes thus constructed, and run the application. And get a stack of exceptions:
Caused by MappingException: Could not determine type for: Account, at table:
product1_type, for columns: [org.hibernate.mapping.Column(from)]
I think the trouble here is that Product1's "from" and "to" properties are not of type Account but of type jaxbgenerated.Account.
I have tried different approaches but to no avail. Some notes:
As I said, all data storage happens on my back-end, so I do not need
the GORM/Hibernate aspect of Grails. Therefore I tried adding
"static mapWith = "none" to the domain classes but that did not
help.
I tried explicitly telling Hibernate the type of the Accounts
in Product1 by adding "static mapping = { from type: Account }" but
that did not work either.
Any help or ideas would be appreciated.
/Jan Reher, Systematic A/S, Denmark
I think you have do write a dababase plugin similar in concept to this simpledb
I have a set of fields that I intend to share between multiple models. I want all the fields to be included in each entity's table (not just one table for the fields). I'm more familiar with languages such as Python, where this type of pattern is called a "mixin", essentially a class that doesn't exist on its own (it doesn't get instantiated/doesn't have a table in the case of a model class). Instead, the derived class simply inherits the fields and its table looks as if the fields were simply included right on the model class.
The concept of a "Complex Type" in Entity Framework seems like a close proxy to what I'm looking for, but the inability to include navigation properties is a bit of killer. Is there any other way to do this, or if Complex Types are the answer, then what should I do about the navigation properties?
I've read this note in a book:
An interesting possibility beyond base classes and interfaces are mixins, but they are an OOP feature not supported by .NET languages. A mixin is a class that provides a certain functionality that other classes can inherit, but it is not meant to be a standalone class. Put another way, a mixin is like an interface where some of the members might contain a predefined implementation. Mixins are supported in some dynamic languages, including Python and Ruby. No .NET languages currently support mixins, but mixins can be simulated using ad hoc frameworks such as Castle. DynamicProxy. With this framework, you first define a class that contains all the methods you want to inject in an existing class—the mixin. Next, you use the framework to create a proxy for a given class that contains the injected methods. Castle.DynamicProxy uses Reflection.Emit internally to do the trick.
You can do this using inheritance. If you've already considered that, I apologize. Code follows.
public abstract class WidgetBase
{
public string Name { get; set; }
}
public class SweetWidget : WidgetBase
{
public int SweetnessFactor { get; set; }
}
public class SourWidget : WidgetBase
{
public int Sourness { get; set; }
}
Then in your model configuration, you do:
const string discriminator = "WidgetType";
Map<SweetWidget>(mc => mc.Requires(discriminator).HasValue("Sweet"));
Map<SourWidget>(mc => mc.Requires(discriminator).HasValue("Sour"));
You will need to add a column, "WidgetType", to your table. EF will then populate it as specified in the mapping.
Note that the base class MUST be abstract. As long as your table contains all of the fields for all of the derived classes, this is how you do Table Per Hierarchy in EF Code First.
Actually had a chance to discuss this with one of the developers on Entity Framework. It's not technically possible at this time. It's apparently being kicked around, but no one is working on it at this point. Complex Types are a sort-of version, but they of course don't support navigation properties. Thanks to everyone who took at stab at it for me.