0

I'm currently on design stage in writing C# .NET Core application. I'm gonna use the generics to inherit some properties among all derived classes. The goal is to archive many 2 many relation of entities able to be tagged. The app concept is funky, because tag will contain related logic as constraint entity. I have problems with the proper where statements in generic class, to be able to use inherited Tags property for all Taggable Entities.

Here is abstraction:

public interface ITaggable
{
    long TagId { get; set; }
    Tag Tag { get; set; }
}

public interface IEntityTag<T> : ITaggable where T : Entity
{
    long EntityId { get; set; }
    T Entity { get; set; }
}

public abstract class TaggableEntity<T> : Entity where T : ITaggable
{
    public ICollection<T> EntityTags { get; set; }
    public List<Tag> Tags { get { return EntityTags.Select(x => x.Tag).ToList(); } }
}

public abstract class ConstraintBase<TSubject, TOwner>
    : ConstraintEntity where TOwner : TaggableEntity<IEntityTag<TOwner>>
{
    protected ConstraintBase(ConstraintId id, string description)
    {
        Id = id.Value();
        Name = id.ToString();
        Description = description;
        IsExecutable = false;
    }

    public IEnumerable<TSubject> Validate(IEnumerable<TSubject> items, TOwner owner)
    {
        return items.Where(x => Validate(x, owner));
    }

    public void Execute()
    {
        if (IsExecutable) { OnExecuting(); }
    }

    protected abstract bool Validate(TSubject item, TOwner owner);
    public abstract void OnExecuting();

}

And here concrete classes.

public class ConstraintEntity : Entity
{
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsExecutable { get; set; }

    public ConstraintId ConstraintId => (ConstraintId)Id;
}

public class EndWorkConstraint : ConstraintBase<Activity, User>
{
    public EndWorkConstraint() : base(ConstraintId.EndWorkConstraint, "Check if user is allowed to end work")
    {
    }

    protected override bool Validate(Activity item, User owner)
    {
        return item.ActivityId != ActivityId.EndWork;
    }

    public override void OnExecuting()
    {
        throw new System.NotImplementedException();
    }
}

public class User : TaggableEntity<UserTag>
{
    public string Login { get; set; }
    public string Password { get; set; }
}

The question is: am I able to modify ConstraintBase where statement, to make EndWorkConstraint class do not raising an error, and still have the tags explicit avalible?

This is my first post on the forum, and I m really forced to use Yours wisdom. I'd be glad for any tips. Thanks in advance.

Sreemat
  • 616
  • 10
  • 28
  • While we can probably guess what your issue is, that would take us some time. So I recommend you to create a [MCVE] from the provided code and specify the exact error you are receiving during the compilation. Recommended reading - http://meta.stackoverflow.com/questions/260648/stack-overflow-question-checklist. – Eugene Podskal Jan 21 '17 at 14:19
  • You are right, it's too time consuming question. But the problem is indeed complicated. Or I've over complicated it event more. I ll try to minimalize it, and focus on technical problem rather that mine one. – Roman Duzynski Jan 21 '17 at 14:25
  • You don't need that many classes with that many properties. And the most important is that it should be Complete - so that anyone can just copy it and see the same errors. – Eugene Podskal Jan 21 '17 at 14:27
  • It would be helpful if you told us the error you are getting. (Or maybe I'm missing something in the long post?) – Peter - Reinstate Monica Jan 21 '17 at 14:29
  • The error says that Type User mus be convertible to TaggableEntity> in order to user it as parameter TOwner in generic class ConstrainBase (int EndWorkConstraint class) I tried to cast User as this in tests but it fails too, but this time compiler said: Cannot convert type (...) to (...) via a reference conversion, boxing conversion via built-in-conversion. I will prepare a test solution for scenarion and paste the ZIP – Roman Duzynski Jan 21 '17 at 14:42
  • Here is link for test case solution [Link](http://www72.zippyshare.com/v/zIX6pEjC/file.html) – Roman Duzynski Jan 21 '17 at 21:20
  • @RomanDuzynski Took a look at your test case. You are violating the fundamentals of generics type constraints. First read up on covariance and contravariance - Also see http://stackoverflow.com/questions/1817300/convert-listderivedclass-to-listbaseclass – tcwicks Feb 01 '17 at 03:51

0 Answers0