How to avoid empty implementation in abstract class while implementing an interface? - c#-2.0

public interface IMyInterface
{
int A { get; set; }
string S { get; set; }
}
public abstract class MyAbs : IMyInterface
{ }
public class ConcreteClass : MyAbs
{
/* Implementation of IMyInterface*/
}
Is it possible to omit the empty implementation in an abstract class as above?
If so, how? why?

you can define the methods/properties as abstract in the abstract class so it won't have empty implementation
The code you provided will not compile
what you need is
public interface IMyInterface
{
int A
{ get; set; }
string S
{ get; set; }
}
public abstract class MyAbs : IMyInterface
{
public abstract int A { get; set; }
public abstract string S { get; set; }
}
public class ConcreteClass : MyAbs
{
/* Implementation of IMyInterface*/
}

The purpose of an abstract class is to encapsulate some common behaviour that applies to all the deriving classes. If you haven't got anything at all in your abstract class then it there is no purpose to having it, ConcreteClass should implement the interface directly.
If you subsequently add another class that also implements this behaviour, then that is the time to refactor and create an abstract base class if it makes sense.

Related

What causes Entity Framework to create a table for a base class?

I keep falling into the trap of declaring an abstract base class for my tables and then finding that the base class is created by the data migration.
I know not to create a DBSet in the context for the table I don't want
The following class does not cause a BasicBo table to create
public abstract class BasicBo : IXafEntityObject //, IObjectSpaceLink we should just declare it when we really need it... mainly we want out business objects to be like POCOs
{
[Browsable(false)]
[Key]
public virtual int Id { get; set; }
public virtual void OnCreated()
{
}
public virtual void OnSaving()
{
}
public virtual void OnLoaded()
{
}
}
However this class does cause a BasicNodeBo table to be created
public abstract class BasicNodeBo : IXafEntityObject
{
[Browsable(false)]
[Key]
public virtual int Id { get; set; }
public virtual int SiblingOrder { get; set; }
public virtual string Sequence { get; set; }
public virtual void RecalculateSequence()
{
}
public virtual void AddDependency(IObjectSpace os, BasicNodeBo sibling)
{
}
public virtual void OnCreated()
{
}
public virtual void OnSaving()
{
}
public virtual void OnLoaded()
{
}
}
I think it may be the presence of BasicNodeBo as a persistant navigation property in a business object..

AutoMapper mapping base class and projection

How do I map this:
public class Domain_1
{
public DomainType DomainType { get; set; }
public Domain_2 Domain2 { get; set; }
public Domain_3 Domain3 { get; set; }
}
to:
public abstract class DTOBase
{
// properties from Domain_1
}
public class DTO_1 : DTOBase
{
// properties from Domain_2
}
public class DTO_2 : DTOBase
{
// properties from Domain_3
}
Ideally,the Domain design should be same as the DTO but I can't due to EF6 and existing database restrictions.
Currently what I have right now is:
this.CreateMap<Domain_1, DTOBase>()
.ConstructUsing(SomeDTOCreatorFactoryMethod);
this.CreateMap<Domain_2, DTO_1>();
What SomeDTOCreatorFactoryMethod does is it creates the DTO based on the DomainType.
This works fine but I wanted to do some projection something like:
var domain_Db = dbContext.Domain1.Where(d => d.Id == 1).ProjectTo<DTOBase>.SingleOrDefault();
// var result = _mapper.Map<Domain1, DTOBase>(domain_Db);
Its throwing an error that cannot instantiate an abstract class. I understand the error but how I can use the factory method in order to create the DTO?
And what if I have to use a custom resolver on certain properties? I know this is not supported but is there a workaround?

Why am I getting MissingMethodException in an Abstract class

I have an abstract class and other classes that inherit from it.
Those classes are below:
[Table("Contents", Schema="Admon")]
public abstract class Content
{
public Content()
{
this.EntryDate = DateTime.Now;
}
[Key]
public int ID { get; set; }
public string Title { get; set; }
public int? ParentID { get; set; }
[StringLength(15)]
public string InfoType { get; set; }
public DateTime EntryDate { get; set; }
public string Preview { get; set; }
public string Description { get; set; }
public string Link { get; set; }
public string Text { get; set; }
public string CategoryID { get; set; }
public int? DocID { get; set; }
public virtual Content Parent { get; set; }
public virtual ICollection<Content> Subs { get; set; }
}
public class Photo : Content { }
public class Notice : Content { }
public class Article : Content { }
public class Calendar : Content { }
My problem is that anytime i run my app it throws an exception that reads
System.MissingMethodException: Cannot create an abstract class
What can I do to rectify this error.
Thanks in advance
To use inheritance in Entity Framework, you have to implement TPH (Table per Hierarchy) or TPT (Table per Type) database structure.
With this strategy, you will be able to implement your expected behavior.
You can follow this article to implement TPH or TPT, and learn about this technology.
Hope it helps !
You cannot create an instance of an abstract class. An abstract class contains abstract members which define what a subclass should contain.
If this class must remain abstract you need to create a second class that inherits from it and implements it's members and use that class to do your processing with.
If the class doesn't have to remain abstract (I can't see why it should be but without seeing the rest of your code I can't be 100% sure) then just remove the abstract keyword.
The class Content would not compile because the your class is abstract. The MVC engine
cannot create an instance of Content directly.Unless you give it some way to know which type of Problem to instantiate, there's nothing it can do.
It is possible to create your own ModelBinder implementation, and tell MVC to use it. Your implementation could be tied to a Dependency Injection framework, for example, so that it knows to create a Content1 whenever a Content class is requested.

Why model binder cannot recover abstract classes after POST?

I'm starting to working on ASP.NET using MVC. I writing to action results, one of them is a HTTP GET and the another HTTP POST
[HttpGet]
public ActionResult DoTest()
{
Worksheet worksheets = new worksheets(..);
return View(w);
}
[HttpPost]
public ActionResult DoTest(Worksheet worksheet)
{
return PartialView("_Problems", worksheet);
}
Now, Worksheet class has a property called Problems and this is a collection, but uses as an abstract class item.
public class Worksheet
{
public List<Problem> Problems { get; set; }
}
Here's my abstract class and one implementation
public abstract class Problem
{
public Problem() { }
public int Id { get; set; }
public abstract bool IsComplete { get; }
protected abstract bool CheckResponse();
}
public class Problem1 : Problem
{
...
public decimal CorrectResult { get; set; }
// this is the only property of my implementation class which I need
public decimal? Result { get; set;}
public override bool IsComplete
{
get { return Result.HasValue; }
}
protected override bool CheckResponse()
{
return this.CorrectResult.Equals(this.Result.Value);
}
}
I have right now, many implementations of Problem class, but I really need to get just one value of my implementation class. But it thrown the above image error.
What can I do to allow model binder recover that part of my abstracts classes
The following code would not compile:
var problem = new Problem();
... because the Problem class is abstract. The MVC engine cannot just create a Problem directly. Unless you give it some way to know which type of Problem to instantiate, there's nothing it can do.
It is possible to create your own ModelBinder implementation, and tell MVC to use it. Your implementation could be tied to a Dependency Injection framework, for example, so that it knows to create a Problem1 whenever a Problem class is requested.
Or you could simply change your action method to take a concrete type:
public ActionResult DoTest(IEnumerable<Problem1> problems)
{
return PartialView("_Problems",
new Worksheet {
Problems = problems.Cast<Problem>().ToList()
});
}

Problem auto mapping => collection of view models instead another view model

I have something like this
public class AViewModel
{
public decimal number { get; set; }
public List<BViewModel> BVM { get; set; }
}
public class BViewModel
{
public string someString{ get; set; }
}
public class SomeObject
{
public decimal number { get; set; }
public List<OtherObjects> BVM { get; set; }
}
public class OtherObjects {
public string someString{ get; set; }
}
Mapper.CreateMap<SomeObject,AViewModel>();
When I have this I get
Trying to map OtherObjects to BViewModel
Using mapping configuration for SomeObject to AViewModel
Destination property: BVM
Missing type map configuration or unsupported mapping.
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
How can I help it figure out how to map it properly?
I believe Automapper needs to know how to convert OtherObject to BViewModel. Try adding a mapping for that too.
You need to specify a typeconverter between OtherObject and BViewModel by specifying a custom type converter
Here's what the converter would look like:
public class OtherToBViewTypeConverter : ITypeConverter<OtherObjects, BViewModel>
{
public BViewModel Convert(ResolutionContext context)
{
if (context.IsSourceValueNull) return null;
var otherObjects = context.SourceValue as OtherObjects;
return new BViewModel { someString = otherObjects.someString; }
}
}
And then the map would be called like this:
Mapper.CreateMap<SomeObject,AViewModel>().ConvertUsing<OtherToBViewTypeConverter>();

Resources