I created the GenericAttribute.cs file in my Models
public class GenericAttributes<T>
{
public T Id { get; set; }
public bool IsActive { get; set; }
public DateTime CreatedDate { get; set; }
}
Now I want to add 'int id' field in my User Model
public class User
{
//here I want to add 'Id' field
public string UserId { get; set; }
public string password { get; set; }
public string UserType { get; set; }
public int EmployeeId { get; set; }
public virtual Employee employee { get; set; }
}
How should I do this? Please help
You can make GenericAttributes an interface so you can implement it where ever.
Such as;
public interface IGenericAttributes<T>
{
//properties
}
And use in your class declaration;
public class User : IGenericAttributes<int>
{
//properties
}
This will force your concrete type User to implement the properties of the interface.
You are getting some conflicting answers due to your naming convention. Any class of the form xxxAttribute is expected to be a subclass of the Attribute class. Attributes are metadata that you can attach to classes, fields, etc. Using reflection you can read these attributes, which is a powerful way to inform various APIs about how to interact with your custom classes - without inheritance or an interface.
If this sort of metadata is your intent, then Barr J's answer is correct. However, if your intent is for the GenericAttributes class to serve as a base class that you can inherit these properties from, then Tom Johnson is correct (although he did change GenericAttributes into an interface instead of a base class, but same result if all you have are properties like this). The latter is most likely what you are looking for.
I would suggest renaming GenericAttributes to something more descriptive, like BaseRecord or IRecord (as an interface), since User looks like data coming from or going to a database.
It would also be handy to have a non-generic version of the class/interface so that you can non-generically reference such records.
public class BaseRecord {
public Type IdType { get; }
private Object _id = null;
public Object Id {
get {
return _id;
}
set {
if(value != null) {
if(!IdType.IsAssignableFrom(value.GetType()))
throw new Exception("IdType mismatch");
}
_id = value;
}
}
public bool IsActive { get; set; }
public DateTime CreatedTime { get; set; }
public BaseRecord(Type idType)
{
if(idType == null) throw new ArgumentNullException("idType");
this.IdType = idType;
}
}
namespace Generic {
public class BaseRecord<T> : BaseRecord
{
new public T Id {
get { return (T)base.Id; }
set { base.Id = value; }
}
public BaseRecord() : base(typeof(T))
{
}
}
}
public class User : Generic.BaseRecord<int>
{}
public class OtherRecord : Generic.BaseRecord<string>
{}
// This inheritence scheme gives you the flexibility to non-generically reference record objects
// which can't be done if you only have generic base classes
BaseRecord r = new User();
r = new OtherRecord();
BaseRecord records[] = { new User(), new OtherRecord() };
To access the id for GenericAttributes class, you'll have to cast User object as base class type.
namespace SampleApp
{
class SampleProgram
{
static void Main(string[] args)
{
User User = new User() { Id = 1 };
var genericAttribute = (User as GenericAttributes<int>);
genericAttribute.Id = 2;
var genericAttributeId = genericAttribute.Id;
var classId = User.Id;
}
}
public class GenericAttributes<T>
{
public T Id { get; set; }
}
public class User : GenericAttributes<int>
{
public new int Id { get; set; }
}
}
Related
I have a problem with C# generics, and I'm not sure about the most elegant solution. I've been programming a while but am new to the C# ecosystem so don't know common terminology for searching.
I'm trying to refactor code to reduce existing copy-paste duplication of classes. It is easy to resolve with one level of generics, but I can't get it working with two.
A very simplified example is below. The core issue is that BaseProfile cannot use any implementation details relating to DetailsA or DetailsB as it does not know the type. So UpdateDetailsId() has to be duplicated in 2 derived classes, instead of having a single Profile class handle it. Keep in mind this is a toy example just to express the relationships. The real classes have tens of fields, but a common subset which we are using in the class in question, so even if DetailsA and DetailsB look identical assume we need both.
public abstract class BaseProfile<TypeOfPerson>
{
public TypeOfPerson Person { get; set; }
}
public class Profile1 : BaseProfile<PersonA>
{
public void UpdateDetailsId(int id)
{
this.Person.Details.Id = id;
}
}
public class Profile2 : BaseProfile<PersonB>
{
public void UpdateDetailsId(int id)
{
this.Person.Details.Id = id;
}
}
public class PersonA
{
public DetailsA Details { get; set; }
}
public class PersonB
{
public DetailsB Details { get; set; }
}
public class DetailsA
{
public int Id { get; set; }
}
public class DetailsB
{
public int Id { get; set; }
}
I can add interfaces as it is referring to all the same fields for each type. However, C# will not allow an interface to include another interface and automatically resolve it in the implementation, because the member has to exactly match i.e. I thought I could just add IDetails Details to the IPerson interface but the fields now need to be type IDetails instead of DetailsA which implements IDetails. If I do that then I lose compiler type safety and can put the wrong Details on the wrong Person.
I have had success doing a public/private field pair like below, but this only validates and throws at runtime when casting value to DetailsA. I'd prefer something safer but I don't know if this is the best option. The goal of this example is a single Profile class, handling multiple Person classes, each with their own Details type that has an int Id field.
public class PersonA : IPerson
{
public IDetails Details
{
get { return _details; }
set { _details = (DetailsA)value; }
}
private DetailsA _details { get; set; }
}
One way of achieving this is by defining the type relationship between PersonA to DetailsA in a generic way, and specify a second generic type on BaseProfile.
Profile1 : BaseProfile<PersonA, DetailsA>
Consider the following code (note that I'm using Net6, so I have all these nullable reference type operators):
public abstract class BaseProfile<TPerson, TDetails>
where TDetails : IDetails, new()
where TPerson : PersonDetails<TDetails>, new()
{
public TPerson? Person { get; set; } = new TPerson();
public virtual void UpdateDetailsId(int id)
{
Person!.Details!.Id = id;
}
}
public class Profile1 : BaseProfile<PersonA, DetailsA>
{
}
public class Profile2 : BaseProfile<PersonB, DetailsB>
{
}
public abstract class PersonDetails<TDetails>
where TDetails : IDetails, new()
{
public virtual TDetails? Details { get; set; } = new TDetails();
}
public class PersonA : PersonDetails<DetailsA>
{
}
public class PersonB : PersonDetails<DetailsB>
{
}
public interface IDetails
{
int Id { get; set; }
}
public class DetailsA : IDetails
{
public int Id { get; set; }
public string? FirstName { get; set; }
}
public class DetailsB : IDetails
{
public int Id { get; set; }
public string? LastName { get; set; }
}
Testing with the following snippet
var profile1 = new Profile1();
var profile2 = new Profile2();
profile1.UpdateDetailsId(10);
profile2.UpdateDetailsId(12);
Console.WriteLine(profile1.Person!.Details!.Id);
Console.WriteLine(profile2.Person!.Details!.Id);
Console.WriteLine();
Update:
Because you included explicit casting in your snippet for Details property getters and setter, I also want to show a pattern using a concrete type inheriting on these generic types -- then demonstrate implicit/explicit operator user-defined conversion patterns.
Add the following declarations:
public abstract class BaseProfile<TPerson>
where TPerson : PersonDetails<GenericDetails>, new()
{
public TPerson? Person { get; set; } = new TPerson();
public virtual void UpdateDetailsId(int id)
{
Person!.Details!.Id = id;
}
public static explicit operator Profile1(BaseProfile<TPerson> details)
{
var profile = new Profile1();
profile.Person!.Details = (GenericDetails)details.Person!.Details!;
return profile;
}
public static explicit operator Profile2(BaseProfile<TPerson> details)
{
var profile = new Profile2();
profile.Person!.Details = (GenericDetails)details.Person!.Details!;
return profile;
}
}
public class GenericProfile : BaseProfile<GenericPerson>
{
}
public abstract class GenericPersonDetails : PersonDetails<GenericDetails>
{
}
public class GenericPerson : GenericPersonDetails
{
}
public class GenericDetails : IDetails
{
public int Id { get; set; }
public static implicit operator DetailsA(GenericDetails details)
{
return new DetailsA() { Id = details.Id };
}
public static implicit operator DetailsB(GenericDetails details)
{
return new DetailsB() { Id = details.Id };
}
}
and, update the testing functional scope:
var profile1 = new Profile1();
var profile2 = new Profile2();
var genericProfile = new GenericProfile();
profile1.UpdateDetailsId(10);
profile2.UpdateDetailsId(12);
genericProfile.UpdateDetailsId(20);
Console.WriteLine(profile1.Person!.Details!.Id);
Console.WriteLine(profile1.Person!.Details!.FirstName ?? "No First Name");
Console.WriteLine(profile2.Person!.Details!.Id);
Console.WriteLine(profile2.Person!.Details!.LastName ?? "No Last Name");
Console.WriteLine(genericProfile.Person!.Details!.Id);
Console.WriteLine(((Profile1)genericProfile).Person!.Details!.FirstName ?? "No First Name");
Console.WriteLine(((Profile2)genericProfile).Person!.Details!.LastName ?? "No Last Name");
Console.WriteLine();
I reposted question on codereview but can not delete this question couse already answer here.
I have some classes:
public abstract class House
{
public string Name { set; get;}
public SomeClass Property1 { set; get;}
public OtherClass Property2 { set; get;}
}
public class WoodenHouse:House
{
public string WoodType { set; get;}
public int WoodAge { set; get;}
}
public class StoneHouse:House
{
public string StoneType { set; get;}
}
And trying to create Factory Method pattern for this:
abstract class Creator
{
public abstract HouseInfo Info { get; set; }
public Creator()
{
}
public abstract House FactoryMethod();
}
class WoodenHouseCreator : Creator
{
public override HouseInfo Info { get; set; }
public WoodenHouseCreator(WoodenHouseInfo info)
{
Info = info;
}
public override House FactoryMethod()
{
var info = Info as WoodenHouseInfo;
var woodenHouse = new WoodenHouse();
woodenHouse.Name = info.Name;
woodenHouse.Floors = info.Floors;
woodenHouse.RoofType = info.RoofType;
woodenHouse.WoodType = info.WoodType;
woodenHouse.WoodAge = info.WoodAge;
return woodenHouse;
}
}
class StoneHouseCreator : Creator
{
public override HouseInfo Info { get; set; }
public StoneHouseCreator(StoneHouseInfo info)
{
Info = info;
}
public override House FactoryMethod()
{
var info = Info as StoneHouseInfo;
var stoneHouse = new StoneHouse();
stoneHouse.Name = info.Name;
stoneHouse.Floors = info.Floors;
stoneHouse.RoofType = info.RoofType;
stoneHouse.StoneType = info.StoneType;
return stoneHouse;
}
}
Here are the classes what contain information to create ahouse:
class HouseInfo
{
public string Name { set; get; }
public int Floors { set; get; }
public string RoofType { set; get; }
}
class WoodenHouseInfo : HouseInfo
{
public string WoodType { set; get; }
public int WoodAge { set; get; }
}
class StoneHouseInfo : HouseInfo
{
public string StoneType { set; get; }
}
And Usage:
var houseInfo = new WoodenHouseInfo
{
Name = "HouseName",
Floors = 2,
RoofType = "Triangle",
WoodType = "Pine",
WoodAge = 100
};
House house;
if(houseInfo is WoodenHouseInfo)
{
var creator = new WoodenHouseCreator(houseInfo);
house = creator.FactoryMethod();
Console.Write((house as WoodenHouse).WoodAge);
}
Full code fiddle.
My problem is how to handle code duplication. I mean there is a lot of lines that fills base House object properties. How can I write that code only once?
Or I should not to use Factory Method?
Currently your factories instantiate the new objects and then fill in all of their properties with the right values. You could split instantiation from property value assignment. Your StoneHouseCreator could instantiate a StoneHouse, use a HousePopulator that populates the values that all objects of type House have in common, and then the StoneHouseCreator could populate the rest of the values that are exclusive to a StoneHouse. That same HousePopulator could also be used by your WoodenHouseCreator, which would then proceed to populate the WoodenHouse-specific properties.
If you want to philosophise about this at a higher level, these are the problems that we run into because of inheritance. Factories, that is the logical separation of object use from object creation, are more naturally suited to cases where you use composition over inheritance. If you are interested more in this, I would recommend reading this excellent article on the topic.
I would like to know, how could I, with AutoMapper, Map one Dto to multiple entities.
Lemme explain.
I've got one Dto, with an enum to describe its type (to avoid having multiple dtos)
Depending on that enum (RelationType here), I would like to map it to the correct Model (Entity, what ever, it's another object that I use in database).
public class BCardDto : IMappedDto
{
public long Id { get; set; }
public BCardRelationType RelationType { get; set; }
public long RelationId { get; set; }
}
Here are is my Model base:
public class BCardModel : IMappedDto
{
public long Id { get; set; }
}
And here the derived model :
public class CardBCardModel : BCardModel
{
// ormlite, ignore that
[Reference]
public CardModel Card { get; set; }
[ForeignKey(typeof(CardModel), ForeignKeyName = "fk_bcard_card")]
public long RelationId { get; set; }
}
How do I map my Dto to the correct Model depending on the enum i've given ?
(I don't wanna use Mapper.Map everywhere but I wanna let mapper do the runtime mapping job)
Here is how I do it for the Model -> Dto
cfg.CreateMap<CardBCardModel, BCardDto>()
.ForMember(s => s.RelationType, expression => expression.UseValue(BCardRelationType.Card))
.IncludeBase<BCardModel, BCardDto>();
Tell me if I do something wrong and explain me why please :)
Thanks by advance,
Blowa.
Let's say you have a setup wherein there is a base class and 2 classes which derive the base class:
public class ModelBase
{
public string Name { get; set; }
}
public class ModelOne : ModelBase { }
public class ModelTwo : ModelBase { }
Let's also say you have a DTO with an enum as below:
public class ModelDto
{
public string Name { get; set; }
public ModelType ModelType { get; set; }
}
public enum ModelType
{
One = 1,
Two = 2
}
So now the task is: How do I map the ModelDto to either ModelOne or ModelTwo depending on the value in ModelDto.ModelType property?
Here is how:
Mapper.Initialize(cfg => cfg.CreateMap<ModelDto, ModelBase>().ConstructUsing(x =>
{
switch (x.ModelType)
{
case ModelType.One:
return new ModelOne { Name = x.Name };
case ModelType.Two:
return new ModelTwo { Name = x.Name };
default:
throw new InvalidOperationException("Unknown ModelType...");
}
}));
Usage
var dto1 = new ModelDto { ModelType = ModelType.One, Name = "ModelOne" };
var dto2 = new ModelDto { ModelType = ModelType.Two, Name = "ModelTwo" };
var one = Mapper.Map<ModelBase>(dto1);
var two = Mapper.Map<ModelBase>(dto2);
Another way to do the mapping is by using dynamic:
public class PersonDto
{
public string Name { get; set; }
}
public class StudentDto : PersonDto
{
public int studentNumber { get; set; }
}
public class EmployeDto : PersonDto
{
public string EmployeId { get; set; }
}
public class Person
{
public string Name { get; set; }
}
public class Student : Person
{
public int StudentNumber { get; set; }
}
public class Employe : Person
{
public string EmployeId { get; set; }
}
Create Map by using:
Mapper.CreateMap<StudentDto, Student>();
Mapper.CreateMap<EmployeDto, Employe>();
Do the Mapping by:
try
{
var student = MapPerson((dynamic) studentDto);
var employe = MapPerson((dynamic) employeDto);
}
catch
{
throw new InvalidOperationException("Unknown ModelType...");
}
And define two Methods
public static Student MapPerson(StudentDto studentDto)
{
return Mapper.Map<StudentDto, Student>(studentDto);
}
public static Employe MapPerson(EmployeDto employeDto)
{
return Mapper.Map<EmployeDto, Employe>(employeDto);
}
The benefit is that you don't need a key and avoid the switch statement
I have the below code in my Application.
public class GeneralInfo
{
private string _id;
private string _name;
public string id
{
set
{
_id = value;
}
get
{
return _id;
}
}
public string name
{
set
{
_name = value;
}
get
{
return _name;
}
}
}
public class SecureInfo
{
private string _password;
public string password
{
set
{
_password = value;
}
get
{
return _password;
}
}
}
public class User
{
}
I need to apply multiple inheritance in the above code ie. the classes GeneralInfo,SecureInfo properties should be accessible in the user class.
I know using interface Multiple inheritance can be achieved. But i need to define the properties in the base class which is restricted in Interface.
How I can achieve this?
C# does not support multiple inheritance. However you can achieve this via multiple interfaces.
public interface ISecureInfo
{
}
public interface IGeneralInfo
{
}
public class UserClass : ISecureInfo, IGeneralInfo {
}
You probably better off encapsulating the data in the class rather than trying to use something to do multiple inheritance here. See this question for some arguments for this.
You can achieve this through interface based inheritance:
public interface IGeneralInfo
{
String Id { get; set; }
String Name { get; set; }
}
public interface ISecureInfo
String Password { get; set; }
}
public class User : IGeneralInfo, ISecureInfo
{
// Implementation of IGeneralInfo
public String Id { get; set; }
public String Name { get; set; }
// Implementation of ISecureInfo
public String Password { get; set; }
}
Or, going one step further, through composition:
public interface IGeneralInfo
{
String Id { get; set; }
String Name { get; set; }
}
public class GeneralInfo : IGeneralInfo
{
public String Id { get; set; }
public String Name { get; set; }
}
public interface ISecureInfo
String Password { get; set; }
}
public class SecureInfo : IGeneralInfo
{
public String Password { get; set; }
}
public class User : IGeneralInfo, ISecureInfo
{
private GeneralInfo generalInfo = new GeneralInfo();
private SecureInfo secureInfo = new SecureInfo();
public String Id {
get { return generalInfo.Id; }
set { generalInfo.Id = value; }
}
public String Name {
get { return generalInfo.Name; }
set { generalInfo.Name = value; }
}
public String Password {
get { return secureInfo.Password; }
set { secureInfo.Password = value; }
}
}
From your sample description, encapsulation might be what you might want to use:
public class Info{
GeneralInfo general;
SecureInfo secure;
...
}
You cannot do multiple inheritance in C# because it is not supported like C++. In C# you can use interfaces for it and implement method and properties. For sample, you could have a base class
public abstract class Entity
{
public string Name { get; set; }
}
You also could have some interfaces:
public interface IPrint
{
void Print();
}
public interface IGenerate
{
void Generate();
}
And use it like multiples inheritance (but it is not, it is just a single inheritance and interfaces)
public class User : Entity, IPrint, IGenerate
{
public void Print()
{
// some code
// here you could access Name property, because it is on base class Entity
}
public void Generate()
{
// some code
}
}
And you could instance it using the abstractions:
Entity e = new User();
IPrint p = new User();
IGenerate g = new User();
User u = new User();
If you need implementations, you could do a hiearachy inherits, for sample:
User inherit from Person that inherit from Entity.
public class Entity
{
public int Id { get; set; }
public void Method()
{
// some code
}
}
public class Person : Entity
{
public string Name { get; set; }
public void AnotherMethod()
{
// some code
}
}
public class User : Person
{
public string Password { get; set; }
public bool CheckUser(string name, string passworkd)
{
// some code
}
}
I think the best would be to seperate the implementation of the interfaces and the real class you have at the end.
What I mean is something like the Bridge Pattern.
Your class (that will implement several interfaces) will just deleagte the method calls to the real implementation, that you can have in a seperate place and only once.
You could also use an approach like this. You would get to the same point than if you would be using multiple inheritance. That way, you could inherit only Entity if you don't need the SecureInfo stuff (i.e. for books and other stuff). Still, I think composition would do better in this case as others say...
class User : SecuredEntity { }
abstract class SecuredEntity : Entity, ISecureInfo
{
public string Password { get; set; }
}
abstract class Entity : IGeneralInfo
{
public string ID { get; set; }
public string Name { get; set; }
}
interface IGeneralInfo
{
string ID { get; set; }
string Name { get; set; }
}
interface ISecureInfo
{
string Password { get; set; }
}
I started using EF with Code First recently and have come upon this issue which has left me rather perplexed. I will appreciate any feedback on this topic which will help me in resolving the said issue.
Please consider the following sample....
public class SomeType
{
public SomeType()
{
Properties = new List<BaseProperty>();
}
public int PrimaryKey { get; set; }
public string Name { get; set; }
public List<BaseProperty> Properties { get; set; }
}
public abstract class BaseProperty
{
public int PrimaryKey { get; set; }
public string PropertyName { get; set; }
// FK set through Type Configuration File.
public SomeType ParentInstance { get; set; }
}
public class PropertyA : BaseProperty
{
// some unique properties.
}
public class PropertyB : BaseProperty
{
// some unique properties.
}
public class PropertyC : BaseProperty
{
// some unique properties.
}
public class PropertyD : BaseProperty
{
// some unique properties.
}
All of this works great with the appropriate type configuration classes which map to 2 tables (1 for 'SomeType' and the second for 'BaseProperty' along with the remaining derived entities through the use of a discriminator column).
Now, due to circumstances beyond my control, I am being forced to modify 'SomeType' to something like this....
public class SomeType
{
public SomeType()
{
PropertiesAB = new List<BaseProperty>();
PropertiesC = new List<PropertyC>();
PropertiesD = new List<PropertyD>();
}
public int PrimaryKey { get; set; }
public string Name { get; set; }
public List<BaseProperty> PropertiesAB { get; set; } // collection of PropertyA and PropertyB
public List<PropertyC> PropertiesC { get; set; } // collection of PropertyC
public List<PropertyD> PropertiesD { get; set; } // collection of PropertyD
}
This would be very fairly easy to do in NHibernate using bags but is there an equivalent implimentation for this in EF using Code First ? Any thoughts ?
I do not want to write my own implimentation of a Collection which will forward and manipulate all operations to be performed on these new lists to a master list which will be actually mapped to the database.
Please ignore any missing "virtual" modifiers or anything else in the above code since it is only meant to be a sample and is NOT actually what I am using.
Thank you for your replies.
Worse comes to Worse, you can do something like this:
public class SomeType
{
public SomeType()
{
Properties = new List<BaseProperty>();
}
public int PrimaryKey { get; set; }
public string Name { get; set; }
public List<BaseProperty> Properties { get; set; }
public List<BaseProperty> PropertiesAB
{
get
{
return Properties.Where(p=>p is PropertyA || p is PropertyB);
}
set
{
//Remove all the properties already in the Properties collection of
//the type A and B and then
Properties.AddRange(value)
}
}
//Same with rest of the properties
}
You can also make the Properties property internal if the class is being used outside the domain layer