I have a repository called PostsRepository
:
public class PostsRepository : IPostsRepository
{
private readonly DatabaseContext context = new DatabaseContext();
public IEnumerable<Post> All()
{
return
context.Posts
.OrderBy(post => post.PublishedAt);
}
public IEnumerable<Post> AllPublishedPosts()
{
return
context.Posts
.OrderBy(post => post.PublishedAt)
.Where(post => !post.Draft);
}
public Post Find(string slug)
{
return context.Posts.Find(slug);
}
public void Create(Post post)
{
post.Slug = SlugConverter.Convert(post.Slug);
post.Summary = Summarize(post.Content);
post.PublishedAt = DateTime.Now;
AttachTags(post);
if (context.Posts.Find(post.Slug) != null)
{
throw new Exception("tag already exists. choose another.");
}
context.Posts.Add(post);
context.SaveChanges();
}
public void Update(Post post)
{
post.Slug = SlugConverter.Convert(post.Slug);
post.Summary = Summarize(post.Content);
AttachTags(post);
if (context.Posts.Find(post.Slug) != null)
{
throw new Exception("tag already exists. choose another.");
}
context.Posts.Add(post);
context.SaveChanges();
}
public void Delete(Post post)
{
context.Posts.Remove(post);
context.SaveChanges();
}
private void AttachTags(Post post)
{
foreach (var tag in post.Tags)
{
if (context.Tags.Any(x => x.Name == tag.Name))
{
context.Tags.Attach(tag);
}
}
}
private static string Summarize(string content)
{
// contrived.
return content;
}
}
I am worried that I might have wound up with a design that is not very testable as it is not apparent to me how to test this code.
I am going to ask another question on SO as to how to unit test this class soon but before I peruse this implementation I would like to ask that you please review my repository implementation.
Particular areas of concern:
- Testability
- I have read countless opinions about what a repository should do. Are there any pragmatic reasons why my implementation might be bad?
- The
PostsRepository
needs to access theTags
database set. Am I allowing this in the correct way? Know that I plan to implement aTagsRepository
in the future. - I throw an exception when the slug (which must be unique) is occupied. Should I return a
bool
to indicate failure instead? Would this not violate the command-query segregation principle? - I am aware that the
Update
method is hard to reason about and I am working on that. It is for this reason that my code does not currently adhere to DRY.