It is clearly explained here how to achieve "multiple inheritance" in C# by using Interface. However, I wonder, how to achieve the same but in the Entity Framework Code First Workflow.
Provided code to make things clear :
public abstract class DomainObject {
// Every business model must have this fields
public Guid Id {get;set;}
public string SystemCode {get;set;}
}
And here also some optional abstract classes like:
public abstract class MultiTitleObject : DomainObject {
public string TitleRu { get; set; }
public string TitleEn { get; set; }
}
public abstract class ManageableByAdminObject : DomainObject {
public bool isVisibleOnSite {get;set;}
public bool isDeletedByAdmin {get;set;}
}
Let's say that I have class that need to have fields of both MultiTitleObject and ManageableByAdminObject and DomainObject as always rule.
Since C# doesn't support multiple inheritance, I can do the following :
public class ManageableByAdminDomainObject : ManageableByAdminObject {
}
public class ManageableByAdminMultiTitleDomainObject : ManageableByAdminDomainObject {
// Even here it's too complicated...
// What if I need to inherit from 3 or more classes?
}
So the solution I wanted to use is Interface like :
public interface IFieldImitation {
bool isVisibleOnSite ();
}
public class ManageableByAdminObject : IFieldImitation, DomainObject {
public bool isVisibleOnSite () => return true;
}
However, EF does understand abstract classes but not the interfaces.
How should I solve this problem?
Related
In my ASP.NET Core API, I have a DTO class BaseBDto and another DerivedBDto that inherits from it, and hides some of its properties, because they're required in DerivedBDto. The properties of BaseBDto and DerivedBDto are objects of another classes, BaseADto and DerivedADto respectively, that follow the same logic as the first ones. I also have a BaseModel class to which both BaseBDto and DerivedBDto will be mapped through another class Mapper.
Something like the following code:
using System.ComponentModel.DataAnnotations;
public class BaseADto
{
public string Name { get; set; }
}
public class DerivedADto : BaseADto
{
[Required]
public new string Name { get; set; }
}
public class BaseBDto
{
public BaseADto A { get; set; }
}
public class DerivedBDto : BaseBDto
{
[Required]
public new DerivedADto A { get; set; }
}
public class BaseModel
{
public string NameModel { get; set; }
}
public static class Mapper
{
public static BaseModel MapToModel(BaseBDto dto) => new BaseModel
{
NameModel = dto.A.Name
};
}
But it turns out, when passing a DerivedBDto object to the MapToModel method, it's trying to access the values of the BaseBDto (which are null) instead of the DerivedBDto ones.
Is there any way I can achieve this behavior?
I can only think of declaring BaseBDto as abstract, but that would prevent me from instantiating it, which I need to do.
PS: I already asked a similar question here, but I oversimplified my code sample, so I felt another question was necessary.
Also, the solution provided there doesn't work because I can't override the A property at DerivedBDto with a DerivedADto since it must have the same type as the A property at BaseBDto.
Have you tried changing the MapToModel signature to be generic. The below
public static BaseModel MapToModel<T>(T dto) where T : BaseBDto => new BaseModel
{
NameModel = dto.A.Name
};
I have a base class for all the ENTITIES of my project which is inheriting from below model :
public class BaseModel
{
public int Id { get; set; }
public int CreatedDate { get; set; }
public override string ToString();
}
Now I have 1 another functionality which is common for so many modules and I want to keep BaseModel for that functionality and want it to be inherited from it.
Public class BaseNotice
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
Now our every model is suppose to inherit from BaseModel so inheriting from BaseNotice will be multiple inheritance.
Now I cannot like below :
Public class BaseNotice : BaseModel
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
Because I would like to control functionality related to Notice from BaseNotice model and for notice I would like to keep BaseNotice as base model.
But I am not getting how to avoid multiple inheritance here and so what would be the proper way to design this?
There is No need to Multiple Inheritance. you can do that in this way:
public class BaseModel
{
public int Id { get; set; }
public int CreatedDate { get; set; }
public override string ToString();
}
public interface IBaseNotice
{
// Base Notices Contracts should be placed here
}
Public class BaseNotice: IBaseNotice
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
public class ModelX:BaseModel
{
public IBaseNotice Notice { get ; set; }
public ModelX(IBaseNotice baseNotice)
{
Notice = baseNotice;
}
}
Or you can use Second Generation of your BaseModel:
public class BaseModeNoticable:BaseModel
{
public IBaseNotice Notice { get ; set; }
public BaseModeNoticable(IBaseNotice baseNotice)
{
Notice = baseNotice;
}
}
I have this abstract class:
public abstract class Task
{
public string ID {get; set;}
public string Name {get; set;}
public abstract class Options{};
public abstract void Execute();
}
I have other classes extending this class:
public class Copy : Task
{
public override void Execute()
{
Console.Write ("running");
}
}
I'd like each derived class to implement their own Options class so they can have their own parameters.
So Search class have to implement it's own Options class with the properties it needs, such as "includesubfolders", "casesensitive", etc..
Meanwhile Move task can implement it's own: "overwrite", etc..
Making properties and methods abstract in an abstract class force derived classes to implement their own but defining a nested abstract class or an interface in the same class does not force it's derived classes implement their own.
I can define each property individually in each derived class but that defeats the purpose since I like to query the properties in Task.Options later in the Execute method.
I tried dynamic object as well, but that brought whole other issues.
You can use a generic
public abstract class Options{};
public class CopyOptions : Options
{
}
public abstract class Task<T> where T : Options
{
public string ID {get; set;}
public string Name {get; set;}
public T Options { get; set; }
public abstract void Execute();
}
public class Copy : Task<CopyOptions>
{
public override void Execute()
{
Console.Write("running");
}
}
You can't enforce a nested class implementation, but you could add a property for the Options:
public abstract class Task
{
public string ID {get; set;}
public string Name {get; set;}
public Options Options {get; set;}
public abstract void Execute();
public abstract class Options{};
}
However there's no way to enforce that the implementation of the Options class be nested within the class that implements Task.
You can always throw a notimplementedexeption exception
I have 2 sets of 2 classes where each pair has a super/sub-class relationship, and the orthogonal pair has a dependency relationship. What I am trying to determine is what to do with the constructors and/or bodies of the properties to keep the model as simple as possible with minimal data duplication.
Here's the structure in code:
public class Base1 {
public List<Base2> MyBase2Things { get; set; }
// Do things with Base2 objects
}
public class Sub1 : Base1 {
public List<Sub2> MySub2Things { get; set; }
// Do things with Sub2 objects and also with Base2 objects
}
public class Base2 {
public Base1 MyBase1 { get; set; }
// Do things with the Base1 object
}
public class Sub2 : Base2 {
public Sub1 MySub1 { get; set; }
// Do things with the Sub1 object
}
I have considered overriding the base properties in the sub-classes, but that doesn't fit very cleanly because the properties in the sub-classes don't have the same signature and so I would have to add properties.
I have also considered setting the base property in the sub-class constructor and set methods, but there is no way for the sub-class property to be updated if the base-class's property is updated.
What other options are there, and which is the cleanest (and why)?
Note: The above code is greatly simplified to illustrate the problem. There are additional properties and methods on the real classes, but this subset is the essence of the trouble I'm having.
I agree with Yaur that generics may help. As far as your options and keeping the model simple as possible - this probably depends on the specifics like the responsibilities of your 4 classes.
Let's say you're dealing with parent/child relationships of various vehicles & vehicle parts.
Scenario 1: The inherited relationship brings in orthogonal capability.
public class ItemParent { // formerly Base1
public List<ItemChild> MyChildren {get; set;}
}
public class ItemChild { // formerly Base2
public ItemParent MyParent {get; set;}
}
public class Car : ItemParent { // formerly Sub1
public List<CarPart> MyParts {get; set;}
}
public class CarPart : ItemChild { // formerly Sub2
public Car ParentCar {get; set;}
}
Of course, Cars should specifically know about CarPart, not ItemChild. So you fall back on generics here.
public class ItemParent<T> where T : ItemChild {
public List<T> MyChildren {get; set;}
}
public class ItemChild<T> where T : ItemParent {
public T MyParent {get; set;}
}
public class Car : ItemParent<CarPart> {}
public class CarPart : ItemChild<Car> {}
public class Truck : ItemParent<TruckPart> {}
public class TruckPart : ItemChild<Truck> {}
You can call subclass.MyChildren[] just fine, or make a MyParts property which delegates to MyChildren.
In this example, I think the model is pretty simple due to the fact that the parent/child metaphor is pretty easy to grok. Plus, if you add Truck-TruckParts (or Household-Resident, Shape-Line, etc.) you're not really increasing the complexity.
An alternative here would be to move the parent/child "responsibility" to a collection object (possibly custom), like so:
public class ParentChildCollection<TParent, TChild> {}
public class Car {
private ParentChildCollection<Car, CarPart> PartHierarchy;
public List<CarPart> MyParts {get { return PartHierarchy.GetMyChildren(this); } }
}
public class CarPart {
private ParentChildCollection<Car, CarPart> PartHierarcy;
public Car ParentCar {get { return PartHierarchy.GetMyParent(this); }}
}
The downside here is that, while clean, Truck and Car might not share a lot of code (if that's what you were wanting).
Scenario 2: The inherited relationship is about specializing to a parallel item.
public class Car { // formerly Base1
public List<CarPart> MyParts {get; set;}
}
public class CarPart { // formerly Base2
public Car MyParent {get; set;}
}
public class Truck : Car { // formerly Sub1
public List<TruckPart> MyParts {get; set;}
}
public class TruckPart : CarPart { // formerly Sub2
public Truck MyParent {get; set;}
}
In this case, Truck and Car do share more code. But this starts running into signature problems that aren't easily solved even with generics. Here, I'd consider making the base class more generic (Vehicle-VehiclePart). Or consider refactoring this second scenario into the first scenario. Or use the collection for parent/child management and the inheritance stictly for Car-Truck code consolidation.
At any rate, I'm not really sure that either scenario matches your case. At least some factor are based on how you have (and how you can) arrange your relationships.
Generics may be able to help you with at least part of this... something like:
public class Base1<T>
where T: Base2
{
public List<T> MyThings { get; set; }
protected Base1(List<T> listOfThings)
{
this.MyThings = listOfThings;
}
}
public class Sub1 : Base1<Sub2>
{
public Sub1(List<Sub2> listofThings):
base(listofThings)
{
}
}
making it work where you need to subclass in both directions can get tricky (and messy) quickly, but will look something like:
// Base 1 hierachy
abstract public class Base1
{
protected abstract Base2 GetBase2(int index); //we can't return the list directly
}
public class Base1<Base2Type> :Base1
where Base2Type : Base2
{
public List<Base2Type> MyBase2s { get; set; }
protected Base1(List<Base2Type> listOfThings)
{
this.MyBase2s = listOfThings;
}
protected override Base2 GetBase2(int index)
{
return MyBase2s[index];
}
}
public class Sub1<MySub1Type,MySub2Type> : Base1<MySub2Type>
where MySub1Type : Sub1<MySub1Type,MySub2Type>
where MySub2Type : Sub2<MySub1Type, MySub2Type>
{
public Sub1(List<MySub2Type> listOfThings):
base(listOfThings)
{
this.MyBase2s = listOfThings;
}
}
public class Sub1 : Sub1<Sub1,Sub2>
{
public Sub1(List<Sub2> listofThings):
base(listofThings)
{
}
}
// base 2 hirachy
abstract public class Base2
{
protected abstract Base1 MyBase1 { get; }
}
public class Base2<Base1Type,Base2Type> : Base2
where Base1Type: Base1<Base2Type>
where Base2Type : Base2
{
public Base1Type myBase1;
protected override Base1 MyBase1{ get {return myBase1;} }
}
public class Sub2<Sub1Type, Sub2Type> : Base2<Sub1Type,Sub2Type>
where Sub1Type : Sub1<Sub1Type,Sub2Type>
where Sub2Type : Sub2<Sub1Type,Sub2Type>
{
}
public class Sub2 : Sub2<Sub1,Sub2>
{
}
I'm having trouble trying to implement a shared method/property between two classes created by the linq2sql designer.
My two classes have two main properties (coming from the db model):
public partial class DirectorPoll
{
public bool Completed {get; set;}
public bool? Reopen { get; set; }
//more properties
}
public partial class StudentPoll
{
public bool Completed {get; set;}
public bool? Reopen { get; set; }
//more properties
}
Now for example I create an abstract class:
public abstract class GenericPoll
{
public abstract bool Completed { get; set; }
public abstract bool? Reopen { get; set; }
public bool CanEdit
{
get
{
if (Completed == false) return true;
if (Reopen.GetValueOrDefault(false) == false) return false;
return true;
}
}
}
Then
public partial class DirectorPoll : GenericPoll
public partial class StudentPoll: GenericPoll
But when I try to compile it says "Director does not implement inherited abstract member GenericPoll.Completed.get". But it is there. So I think I'm forced to put an override to the property automatically generated by the designer, but if I update the database later and recompile it will give me the same error.
I think I might be missing something here but I've tried different approaches with no success. ¿So what can I do here, besides implementing CanEdit in each of my partial classes? Thanks
It isn't implemented as an override, so it doesn't count. However, implicit interface implementations do count, so this works:
partial class DirectorPoll : IGenericPoll {}
partial class StudentPoll : IGenericPoll {}
public interface IGenericPoll
{
bool Completed { get; set; }
bool? Reopen { get; set; }
}
public static class GenericPoll {
public static bool CanEdit(this IGenericPoll instance)
{
return !instance.Completed || instance.Reopen.GetValueOrDefault();
}
}
One option: create an interface containing Completed and Reopen, make the classes implement the interface (via the manual bits of the partial classes), then write an extension method which extends that interface. I think that should work:
public interface IPoll
{
bool Completed {get; set;}
bool? Reopen { get; set; }
}
// Actual implementations are in the generated classes;
// no need to provide any actual code. We're just telling the compiler
// that we happen to have noticed the two classes implement the interface
public partial class DirectorPoll : IPoll {}
public partial class StudentPoll : IPoll {}
// Any common behaviour can go in here.
public static class PollExtensions
{
public static bool CanEdit(this IPoll poll)
{
return !poll.Completed || poll.Reopen.GetValueOrDefault(false);
}
}
Admittedly then it has to be a method rather than a property, as there's no such thing as an extension property, but that's not too much of a hardship.
(I believe my refactoring of your logic in CanEdit is correct. All those explicit trues and falses were doing my head in ;)