How can I set the state of an object in this class hierarchy? - oop

I have designed my classes with this hierarchy to achieve
RepositoryBase to have some functionalities that can be used by derived classes.
The derived classes implement validation and saving.
Use the IRepository interface (rather than numerous customer interfaces) to register with a IoC container to get the instance of the repository, for example CustomerRepository in this example.
The problem that I have with this design is that the customer object is not known at the construction of the CustomerRepository. It has to be set before save.
How can I redesign this hierarchy to achieve the three that mentioned at the beginning of this question?
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public void string GetFullName();
}
public interface IRepository
{
void Save();
}
public abstract class RepositoryBase<T> : IRepository
{
public abstract bool IsValid();
}
public class CustomerRepository : RepositoryBase<Customer>
{
public void Save()
{
IsValid(); // Check for validation
customer.GetFullName(); // Generate the FullName before saving
// Save the data using some RepositorBase method.
}
}

Related

How do we send a message with Object type or a abstract class to the masstransit message

Currently, I want to pass an object type to the message to avoid reading the DB twice.
But my solution which has the RabbitMQ is not a reference to the domain entities, it only has the abstract class and the interface of the entities.
So, Is there any way to pass an abstract class or interface to the message of the RabbitMQ?
Thank you for your advices!
public interface IDomainEntity
{
// The rest of the code
}
public abstract class Person
{
// The rest of the code
}
public class Employee
{
// The rest of the code
}
public class Employee: IDomainEntity, Person
{
// The rest of the code
}
public class RefreshEmployeeCache : CorrelatedBy<Guid>
{
public Guid EmployeeId { get; set; }
public Person Employee { get; set; } // or public IDomainEntity Employee { get; set; } Can we use this or an althernative way?
public bool IsDeleted { get; set; }
public Guid CorrelationId { get; set; } = Guid.NewGuid();
}
You should be able to cast the message to an object, which should use the Publish(object message) overload (or the Send(object message) overload), allows whatever concrete type is present to be published.
Consumers can implement IConsumer<Person>, providing access to the properties of Person. The subclass type would only be available if it is known to the consumer and requested specifically.

Current user (ASP.NET Identity) information within Generic repository pattern

I have implemented generic repository pattern over an EF Core context, for example;
public class GenericRepository<TEntity, TContext> : IGenericRepository<TEntity>
where TEntity : EntityBase
where TContext : DbContext
{
internal TContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(TContext context)
{
this.context = context;
dbSet = context.Set<TEntity>();
}
public virtual TEntity GetById(long id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
entity.CreatedDate = DateTime.Now;
dbSet.Add(entity);
}
//... additional methods removed for brevity
}
All my models are using an EntityBase class that allows me to record when the record was created and by whom, for example;
public abstract class EntityBase {
public long Id { get; set; }
public DateTime CreatedDate { get; set; }
public string CreatedBy { get; set; }
//... additional fields removed for brevity
}
What are the different ways to access the current user within the repository, so I can add the user to the entity on creation;
public virtual void Insert(TEntity entity)
{
entity.CreatedBy = CurrentUser.Name; // TODO: get current user here?
entity.CreatedDate = DateTime.Now;
dbSet.Add(entity);
}
It feels like I should be able to do this via middleware and or injection.
I think, you should pass user information from controller to the repository method or set CreatedBy value inside the controller instead of Repository method. Moreover , in my opinion you should avoid depend your repository to the identity and keep it simple and independent.
In other words, referencing HttpContext.User.Identity inside your repository is not a good idea,and HttpContext belog to the Presentation Layer not Data Layer.

Fluent Nhiberante sub class same table as class

I have two classes:
class User {
public int Id { get;set; }
public string Name { get; set; }
}
class VerifiedUser : User {
public ICollection<Verified> { get; set; }
}
I would like NHibernate to treat VerifiedUser and User as the same table but keep them separate to, so.
Session.Query<User>() //would return a User
Session.Query<VerifiedUser>() //would return a VerifiedUser
Is this possible or is it unsupported?
You will need to implement the table-per-hierarchy strategy with Fluent Nhiberate in mapping classes. These are like overrides for the AutoMapping feature (if used) of FNH, otherwise mapping classes are de facto and you will be used to them.
Something like:
public class UserMappingOverride : IAutoMappingOverride<User>
{
public void Override(AutoMapping<User> mapping)
{
mapping.DiscriminateSubClassesOnColumn("IsVerified").Not.Nullable();
}
}
public class VerifiedUserClassMap : SubclassMap<VerfiedUser>
{
public VerifiedUserClassMap()
{
DiscriminatorValue("Yes");
}
}
And to answer your question, yes as far as I remember nothing to do here: Session.QueryOver<VerifiedUser>() as NHibernate will add on the where clause for the discriminator

ORM with entity classes and domain interfaces/classes

I'm trying to decide how to handle domain-level classes and interfaces with respect to objects populated via ORM (NHibernate in this case). I've mocked up a very simple scenario that helps to illustrate my current situation.
public interface ICar
{
public bool PassesEmisionStandards(string state);
public int Horsepower { get; set; }
public string Model { get; set; }
}
public class CarFromDB
{
public int Horsepower { get; set; }
public string Model { get; set; }
}
public class ModelT : CarFromDB, ICar
{
public bool PassesEmissionStandards(string state)
{
return false;
}
public override string ToString()
{
return Model + " with " + Horsepower + " ponies";
}
}
In this case, CarFromDB is the class that's got the mapping via NHibernate to my database. ICar is the interface that my UI/Controller code is handling. ModelT is one of the classes that have instances passed to the UI.
In my actual domain, the PassesEmissionStandards is a complicated method that differs significantly among the different derived classes, and the CarFromDB class has a dozen simple properties along with references to other classes, both singly and in lists. This information is all used in the PassesEmissionStandards equivalent.
I'm confused about the best way to end up with my derived classes decorated with the interface when I start with a populated base class from the ORM. The ideas I've come up with to try to handle this are:
Decorate CarFromDB with ICar and try to come up with a clean way to implement the extensive PassesEmissionStandards method within it or by calling out to other classes for help
Use AutoMapper or the equivalent + a factory to transform my base class objects into derived class objects
Since the derived class type can be identified from a property in the base class, mapp my derived classes for NHibernate and find some way to hook into NHibernate to instruct it which mapped derived class to use.
I feel like this must be a very common issue, but I searched around SO and other places without finding any solid guidelines. Please note: I'm relatively new to ORM and domain modelling and very new to NHibernate. Any help is appreciated.
I don't think that I understand your problem, why canĀ“t you use:
public interface ICar
{
public bool PassesEmisionStandards(string state);
public int Horsepower { get; set; }
public string Model { get; set; }
}
public abstract class CarBase : ICar
{
public int Horsepower { get; set; }
public string Model { get; set; }
public abstract bool PassesEmisionStandards(string state);
}
Or if CarBase is used for all derived classes too, you might want to use strategy pattern
public interface IEmissionCalculator
{
void Calculate(IEmissionCalculatorContext context);
}
public CarBase : ICar
{
internal void Assign(IEmissionCalculator calculator){}
public bool PassesEmisionStandards(string state)
{
//assign all info needed for calculations
var ctx = new IEmissionCalculatorContext { };
return _calculator.Check(ctx);
}
}
You can use the same DB-class, but assign different emission caluclations depending of the type of car.
If that doesn't work either, I would use automapper.

Is an interface or an abstract class or both better in the following situation?

Assume I have some program that pulls airline data. Each airline data uses a different system in which I need to pull the data (xml) from. Because of the difference in each system, basically the xml being different and maybe some propeterties, I decide to implement an interface to implement for each airline system. What I find though is that each airline, although different in many aspects, also contains many similarities, so if I do it the interface way first, I might have to do something like this:
public interface IAirlineSystem {
public void PullData();
}
Now for each airline system (I am making these names up), I might do something like:
public class Oberon : IAirlineSystem {
string Name {get;set;}
int Code {get;set;}
public void Initialize()
{
//initialize code here
}
public void PullData()
{
//code here
}
}
The above is just one airline system, but imagine I have more (like +10), another one might be:
public class AirSys: IAirlineSystem {
string Name {get;set;}
int Code {get;set;}
public void Initialize()
{
//initialize code here
}
public void PullData()
{
//code here
}
}
In the code above:
The name and code properties are unique to each Airline system. Initialize contains the exact same code for each implementation and PullData is unique to each system. Because of duplicates in the classes, is this where I could use an abstract class to hold the code of the Initialize method. I have heard that it is good practice to actually mix interfaces and abstract classes, what would be an example of this using my airline system example?
Another thing that comes up is that lets assume that I have another method in the interface called ValidateData, but not all airline systems need to call it, but if I put it in an interface, I would need to implement an empty method if it is not needed. Is there a way I can prevent from having to do this. Is this another reason for using an abstract class, maybe with a virtual method, so it can be overridden as needed. If I made ValidateData an abstract method, it would still need to be implemented, right?
Your explanation seems to point towards using an abstract class. You could have an abstract class that would have an implementation of the Initialize method, and you would not need to repeat it in the Oberon and AirSys subclasses. PullData could be an abstract method that would then get implemented in the separate subclasses. And yes, only the class that requires the ValidateData method would have it implemented.
Example would be:
public abstract class AirlineSystemBase
{
string Name { get; set; }
int Code { get; set; }
public void Initialize()
{
//code goes here
}
public abstract void PullData();
}
public class Oberon : AirlineSystemBase
{
public override void PullData()
{
//code goes here
}
}
public class AirSys : AirlineSystemBase
{
/// <summary>
/// that is if say only AirSys class had a need for this ValidateData() method
/// </summary>
public void ValidateData()
{
//code goes here
}
public override void PullData()
{
//code goes here
}
}
OR if you want to use both interface and abstract class:
public interface IAirlineSystem
{
void PullData();
void ValidateData();
}
public abstract class AirlineSystemBase : IAirlineSystem
{
string Name { get; set; }
int Code { get; set; }
public void Initialize()
{
//code goes here
}
public abstract void PullData();
public virtual void ValidateData()
{
//code goes here
}
}
public class Oberon : AirlineSystemBase
{
public override void PullData()
{
//code goes here
}
}
public class AirSys : AirlineSystemBase
{
/// <summary>
/// that is if say only AirSys class had a need for this ValidateData() method
/// </summary>
public override void ValidateData()
{
//code goes here
}
public override void PullData()
{
//code goes here
}
}
An example, I would implement something like:
public interface IAirlineSystem {
public void PullData();
public void ValidateData();
}
public abstract class BaseAirlineSystem : IAirlineSystem {
string Name {get;set;}
int Code {get;set;}
public void Initialize()
{
// common initialize code here
}
public virtual void ValidateData()
{
//empty, override when necessary
}
}
And a sample implementation:
public class AirSys: BaseAirlineSystem{
public void PullData()
{
//code here
}
}