The class of the base object. NHibernate

It would be good practice to implement the same base entity class:

[Serializable] public abstract class Entity<T> : IComparable<Entity<T>>, IFormattable { public abstract Int32 CompareTo(Entity<T> entity); public abstract String ToString(String format, IFormatProvider provider); // ... } 

Therefore, all derived classes must implement these interfaces. Is it possible to place the IComparable<T> interface in an entity class? Thanks!

+4
source share
3 answers

This is not a good (or bad) practice - it completely comes down to your needs.

Indication of IComparable at the general level is associated with the risk that it may not make sense to compare some objects further in the inheritance chain. Even if you can compare two objects, would it always make sense? You may need to write lines of code to satisfy a contract that will never be used - beware of the YAGNI terms .

However, this would be good if you need to create an absolute contract so that you can compare any objects inherited from Entity. This allows you to make positive assumptions in your code.

+3
source

What will be T? Your domain class? If this is the case, why not make the Entity class non-generic and directly inherit from Entity?

In general, I found that it is good practice to get all the domain classes that can be processed by a specific repository from a common interface or base class. This allows the repository to be common to this interface, providing compile-time checks when you try to use the repository to preserve what the repository maps. However, if you use a base class, do not match it unless you need a way to uniquely identify any Entity, regardless of its actual type of subclass; otherwise, you will receive this Entity table (with any common fields) as a table in your database, and it may be difficult for you to manually track your data level.

However, a generic, displayed Entity may be desirable; You can uniquely identify Persons and Companies by a common column of identifiers, which is unique even through Persons and Companies, which are stored in different tables.

Here is a sterilized example of a hierarchy that I used in one of my projects:

 //identifies a class as persistable, and requires the class to specify //an identity column for its PK public interface IDomainObject { long Id {get;} } //In a repository-per-DB model, just because it an IDomainObject doesn't mean //a repo can work with it. So, I derive further to create basically "marker" //interfaces identifying domain objects as being from a particular DB: public interface ISecurityDomainObject:IDomainObject { } public interface IDataDomainObject:IDomainObject { } public interface IData2DomainObject:IDomainObject { } //There may be logic in your repo or DB to prevent certain concurrency issues. //You can specify that a domain object has the necessary fields for version-checking //either up at the IDomainObject level, a lower level, or independently: public interface IVersionedDomainObject:IDomainObject { long Version {get;} string LastUpdatedBy {get;} DateTime LastUpdatedDate {get;} } //Now, you can use these interfaces to restrict a Repo to a particular subset of //the full domain, based on the DB each object is persisted to: public interface IRepository<TDom> where TDom:IDomainObject { //yes, GTPs can be used as GTCs T GetById<T>(long Id) where T:TDom; void Save<T>(T obj) where T:TDom; //not only must the domain class for SaveVersioned() implement TRest, //it must be versionable void SaveVersioned<T>(T versionedObj) where T:TDom, IVersionedDomainObject } //and now you can close TDom to an interface which restricts the concrete //classes that can be passed to the generic methods of the repo: public class ISecurityRepo:IRepository<ISecurityDomainObject> { ... } 
+2
source

If your objects require comparability and formatting than using a base class, this is a very good practice. sometimes the identification field is also implemented in the base class.

0
source

All Articles