I've build a generic (abstract) builder which will provide basic implementation for entity builders that will be used during testing.
This is the entity base class:
public abstract class Entity : IObjectState
{
[NotMapped]
public ObjectState ObjectState { get; set; }
}
This is the IKey interface:
public interface IKey
{
int Id { get; set; }
}
This is the Builder class:
public abstract class Builder<T> where T : Entity, IKey, new()
{
protected int _id { get; set; }
protected ObjectState _objectState { get; set; }
public Builder()
{
_objectState = ObjectState.Added;
}
public virtual Builder<T> WithId(int id)
{
this._id = id;
return this;
}
public virtual Builder<T> HavingObjectState(ObjectState objectState)
{
_objectState = objectState;
return this;
}
public static implicit operator T(Builder<T> builder)
{
return new T
{
Id = builder._id,
ObjectState = builder._objectState
};
}
}
This is a sample UnitBuilder implementation:
public class UnitBuilder : Builder<Unit>
{
private string _shortDescription;
private string _longDescription;
public UnitBuilder WithShort(string shortDescription)
{
_shortDescription = shortDescription;
return this;
}
public UnitBuilder WithLong(string longDescription)
{
_longDescription = longDescription;
return this;
}
public static implicit operator Unit(UnitBuilder builder)
{
return new Unit
{
Id = builder._id,
ObjectState = builder._objectState,
Short = builder._shortDescription,
Long = builder._longDescription
};
}
}
And this is the problem I'm having:
The error:
Error CS1061 'Builder' does not contain a definition for 'WithShort' and no extension method 'WithShort' accepting a first argument of type 'Builder' could be found (are you missing a using directive or an assembly reference?)
I understand what is going on but I would like a better (more elegant) solution than thirdUnit
.
UPDATE:
As per suggestion I added the following to the UnitBuilder
class:
public new UnitBuilder WithId(int id)
{
return (UnitBuilder)base.WithId(id);
}
public new UnitBuilder WithObjectState(ObjectState objectState)
{
return (UnitBuilder)base.WithObjectState(objectState);
}
But now I don't see any point in the base class... This has to be a
general generic base class problem, how do other people handle this?
Maybe the thirdUnit
solution IS elegant but I'm just being difficult about it? :)