gpt4 book ai didi

asp.net-mvc - Kigg MVC 应用程序是否干燥?我们可以调整存储库吗

转载 作者:行者123 更新时间:2023-12-03 08:39:11 26 4
gpt4 key购买 nike

我最近查看了 Kazi Manzur Kigg MVC 实现(Kazi rock),并注意到一些似乎违反 DRY/SOC 原则的代码。我很想听听每个人对可能的重构以分离关注点的想法。

Kigg 实现了 AddRemove每个存储库类上的方法(注意:BaseRepository 具有虚拟方法,每个具体实现都可以重载。)
Kigg.Repository.LinqToSql.CategoryRepository 的实现和 Kigg.Repository.LinqToSql.StoryRepository两个级联删除都通过它们的Remove方法以删除子实体。 (注意:Category 与 Story 具有父关系(一对多),因此它们从 Story 到对象图共享相同的子关系)see diagram .有问题的代码是两个存储库相互删除子实体的方式:

类别存储库

namespace Kigg.Repository.LinqToSql.CategoryRepository{
//using statements omitted
public class CategoryRepository : BaseRepository<ICategory, Category>, ICategoryRepository
{
//code omitted

public override void Remove(ICategory entity)
{
Check.Argument.IsNotNull(entity, "entity");

Category category = (Category) entity;

Database.DeleteAll(Database.StoryViewDataSource.Where(v => v.Story.CategoryId == category.Id));
Database.DeleteAll(Database.CommentSubscribtionDataSource.Where(cs => cs.Story.CategoryId == category.Id));
Database.DeleteAll(Database.CommentDataSource.Where(c => c.Story.CategoryId == category.Id));
Database.DeleteAll(Database.VoteDataSource.Where(v => v.Story.CategoryId == category.Id));
Database.DeleteAll(Database.MarkAsSpamDataSource.Where(sp => sp.Story.CategoryId == category.Id));
Database.DeleteAll(Database.StoryTagDataSource.Where(st => st.Story.CategoryId == category.Id));
Database.DeleteAll(Database.StoryDataSource.Where(s => s.CategoryId == category.Id));

base.Remove(category);
}
}
}

故事库

namespace Kigg.Repository.LinqToSql
{

//using statements omitted


public class StoryRepository : BaseRepository<IStory, Story>, IStoryRepository
{

//code omitted


public override void Remove(IStory entity)
{
Check.Argument.IsNotNull(entity, "entity");

Story story = (Story) entity;

Database.DeleteAll(Database.StoryViewDataSource.Where(sv => sv.StoryId == story.Id));
Database.DeleteAll(Database.CommentSubscribtionDataSource.Where(cs => cs.StoryId == story.Id));
Database.DeleteAll(Database.CommentDataSource.Where(c => c.StoryId == story.Id));
Database.DeleteAll(Database.VoteDataSource.Where(v => v.StoryId == story.Id));
Database.DeleteAll(Database.MarkAsSpamDataSource.Where(sp => sp.StoryId == story.Id));
Database.DeleteAll(Database.StoryTagDataSource.Where(st => st.StoryId == story.Id));

base.Remove(story);
}
}

}

我是否正确假设更好的设计将具有 CategoryRepository调用 Remove StoryRepository 上的方法,从而将对 Story 的子对象移除的关注委托(delegate)给 StoryRepository它属于哪里?从维护的角度来看,任何添加到 Story 的 child 都需要 DeleteAll要添加到 CategoryRepository 的调用和 StoryRepository .

什么是更好的实现方式?

如果 CategoryRepository重构为使用 StoryRepository直接地?:
CategoryRepository(重构)

namespace Kigg.Repository.LinqToSql.CategoryRepository{
//using statements omitted
public class CategoryRepository : BaseRepository<ICategory, Category>, ICategoryRepository
{
//code omitted

public override void Remove(ICategory entity)
{
Check.Argument.IsNotNull(entity, "entity");

Category category = (Category) entity;

// refactor - start
StoryRepository _storyRepository = new StoryRepository( Database );
category.Stories.ForEach( story => _storyRepository.Remove( story ) );
// refactor - end

base.Remove(category);
}
}
}

此重构将允许 CategoryRepository重用 StoryRepository 中的删除逻辑并且还应该重用相同的 LinqToSql DataContextDatabase 引用给 StoryRepository 的参数构造函数。但是当涉及到单元测试时,它开始有异味。

更好的重构包括使用 IoC(Kigg 使用 Unity 作为其 Ioc 容器)来注入(inject) PerWebRequest IStoryRepository 的范围实例进入 CategoryRepository的构造函数?

CategoryRepository(重构采取 2)

namespace Kigg.Repository.LinqToSql.CategoryRepository{
//using statements omitted
public class CategoryRepository : BaseRepository<ICategory, Category>, ICategoryRepository
{


private readonly IStoryRepository _storyRepository;

public CategoryRepository(IDatabase database, IStoryRepository storyRepository) : base(database)
{
Check.Argument.IsNotNull(storyRepository, "storyRepository");
_storyRepository = storyRepository;
}

public CategoryRepository(IDatabaseFactory factory, IStoryRepository storyRepository) : base(factory)
{
Check.Argument.IsNotNull(storyRepository, "storyRepository");
_storyRepository = storyRepository;
}

//code omitted

public override void Remove(ICategory entity)
{
{
Check.Argument.IsNotNull(entity, "entity");

Category category = (Category) entity;

// refactor - start
category.Stories.ForEach( story => _storyRepository.Remove( story ) );
// refactor - end

base.Remove(category);
}
}
}

通过第二次重构,我们现在可以注入(inject) IStoryRepository 的实例。进入 CategoryRepository在单元测试期间和通过 Unity Ioc。当然,我们必须将此重构扩展到每个存储库类,以便他们可以倾向于自己 child 的责任。

大家的想法是什么?

最佳答案

请原谅我对 L2S 的无知(我使用 NHibernate),但它不会自动处理级联吗?

关于asp.net-mvc - Kigg MVC 应用程序是否干燥?我们可以调整存储库吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1139446/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com