I feel like this is an anti pattern of some sort, but basically I've got 2 versions of the same type of repo that have the same type of properties and methods. I played with the idea of both an interface and an abstract class but in neither case can I get around what appears to be unnecessary checks. Here's the premise (using abstract class):
public abstract class BaseRepository
{
public abstract RepositoryType RepositoryType { get; } //enum of File or DataBase
public abstract CreateResult CreateItem (Item item);
public abstract DeleteResult DeleteItemById(Guid Id);
public abstract Item GetItem(Guid Id);
}
public class Item
{
public Guid Id { get; }
public string Name { get; }
public ItemType ItemType { get; } //enum of File or DataRecord
//other props...
}
public FileRepository : BaseRepository
{
public override RepositoryType RepositoryType => RepositoryType.File
public override CreateResult CreateItem(Item item)
{
if(item.ItemType != ItemType.File) throw InvalidOperationException("some error message") //problem is here
//some logic.
}
//other overrides....
}
So there's a basic contract created for a repository via the BaseRepository, which is overridden by the FileRepository. An item basically has the same stuff whether it's a File item or a DataRecord item (there could arguably be an IItem interface and then 2 separate Items of DataRecord and File rather than an enum but that still doesn't solve the problem).
The problem is I don't see how I can pass in an Item with only ItemType File to the FileRepository. It feels like there should be a way of making sure that the FileRepository only receives items of type File and that a check shouldn't have to be made to ensure it's got the right type. How can I do this?
Make the repository generic, and introduce types for each type of item. eg:
public abstract class Item
{
}
public class FileItem : Item
{
}
public abstract class Repository<TItem> where TItem : Item
{
public virtual string RepositoryType => typeof(TItem).Name;
public abstract CreateResult CreateItem(TItem item);
public abstract DeleteResult DeleteItemById(Guid Id);
public abstract Item GetItem(Guid Id);
}
public class FileRepository : Repository<FileItem>
{
public override CreateResult CreateItem(FileItem item)
{
throw new NotImplementedException();
}
public override DeleteResult DeleteItemById(Guid Id)
{
throw new NotImplementedException();
}
public override Item GetItem(Guid Id)
{
throw new NotImplementedException();
}
}