我有一个问题,希望帮助我。我有一些服务类,例如,我显示其中一个的一部分:
public class CategoriesService : ICategoriesService
{
public List<Categories>? getAll()
{
return RYCContextService.getInstance().BBDD.categories?.ToList();
}
.
.
.
}
然后,我有这样的类:
public class TransactionsService : ITransactionsService
{
private readonly ISplitsService splitsService;
private readonly ICategoriesService categoriesService;
private readonly IAccountsService accountsService;
public TransactionsService(ISplitsService splitsService,ICategoriesService categoriesService,
IAccountsService accountsService)
{
this.splitsService = splitsService;
this.accountsService = accountsService;
this.categoriesService = categoriesService;
}
public List<Transactions>? getAll()
{
return RYCContextService.getInstance().BBDD.transactions?.ToList();
}
.
.
.
}
它使用类别类和其他类,我在它们上使用注入的依赖项,并通过构造函数参数传递服务以解析这些依赖项。
此类服务在表单中使用,例如:
public partial class FrmTransaction : Window
{
private Transactions? transaction;
private readonly int? accountidDefault;
private readonly IAccountsService accountsService;
private readonly ICategoriesService categoriesService;
private readonly IPersonsService personsService;
private readonly ITagsService tagsService;
private readonly ISplitsService splitsService;
private readonly ITransactionsService transactionsService;
private readonly ITransactionsStatusService transactionsStatusService;
public FrmTransaction(IAccountsService accountsService, ICategoriesService categoriesService,
IPersonsService personsService, ITagsService tagsService,ITransactionsService transactionsService,
ITransactionsStatusService transactionsStatusService, ISplitsService splitsService)
{
this.accountsService = accountsService;
this.categoriesService = categoriesService;
this.personsService = personsService;
this.tagsService = tagsService;
this.transactionsService = transactionsService;
this.transactionsStatusService = transactionsStatusService;
this.splitsService = splitsService;
InitializeComponent();
}
. . . . .
. . . .
. . . .
}
此窗体是从主窗体调用的:
public partial class MainWindow : Window
{
private readonly IAccountsService accountsService;
private readonly IAccountsTypesService accountsTypesService;
private readonly ICategoriesService categoriesService;
private readonly ICategoriesTypesService categoriesTypesService;
private readonly ITransactionsService transactionsService;
private readonly ITransactionsRemindersService transactionsRemindersService;
private readonly IExpirationsRemindersService expirationsRemindersService;
private readonly ISplitsService splitsService;
private readonly ISplitsRemindersService splitsRemindersService;
private readonly IPeriodsRemindersService periodsRemindersService;
private readonly IPersonsService personsService;
private readonly ITagsService tagsService;
private readonly ITransactionsStatusService transactionsStatusService;
public MainWindow(IAccountsService accountsService, ITransactionsService transactionsService,
ISplitsService splitsService, IExpirationsRemindersService expirationsRemindersService,
ICategoriesService categoriesService,ICategoriesTypesService categoriesTypesService,
IAccountsTypesService accountsTypesService,IPersonsService personsService,
ITagsService tagsService, ITransactionsRemindersService transactionsRemindersService,
ITransactionsStatusService transactionsStatusService, ISplitsRemindersService splitsRemindersService,
IPeriodsRemindersService periodsRemindersService)
{
InitializeComponent();
this.accountsService = accountsService;
this.transactionsService = transactionsService;
this.splitsService= splitsService;
this.expirationsRemindersService = expirationsRemindersService;
this.categoriesService = categoriesService;
this.categoriesTypesService = categoriesTypesService;
this.accountsTypesService = accountsTypesService;
this.personsService = personsService;
this.tagsService = tagsService;
this.transactionsRemindersService = transactionsRemindersService;
this.transactionsStatusService = transactionsStatusService;
this.periodsRemindersService = periodsRemindersService;
this.splitsRemindersService = splitsRemindersService;
}
private void gvTransactions_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (gvTransactions.CurrentItem != null)
{
FrmTransaction frm = new FrmTransaction((Transactions)gvTransactions.CurrentItem,accountsService,categoriesService,
personsService,tagsService,transactionsService,transactionsStatusService,splitsService);
frm.ShowDialog();
loadAccounts();
loadTransactions();
refreshBalance();
}
}
....
....
.....
}
我认为有一些东西是不正确的,因为代码对我来说是非常丑陋的,对于我从主体类调用的每个窗体,增量类变量和构造函数参数,它不用于主体窗体,只用于传递到下一个窗体。
1条答案
按热度按时间k10s72fa1#
您的代码存在一些设计问题,导致您目前的情况是感觉代码难以维护。根据您希望代码有多干净、应用程序有多大(以及它需要多大的可扩展性),您可以将设计问题归类为严重问题:
问题
您的构造函数可能有太多的参数。这表明您的类可能有太多的依赖项,这意味着它有太多的责任。您应该重新审视您的类设计。这个问题会使您的代码难以理解,即使是您自己。
溶液
应用"单一责任原则"(SOLID中的"S"),将大类拆分为许多较小的类。将功能从定义了太多依赖项和责任的类中移除。这也有助于更好地理解代码。
问题
你到处散布
RYCContextService.getInstance
。看起来你在这里实现了 * Singleton * 模式。你应该总是避免它。特别是在使用依赖注入(或任何形式的IoC)的环境中,你不需要 * Singleton 。你通常使用依赖注入来使你的应用程序具有可扩展性。给
static
示例添加一个紧耦合会使目标落空。它还引入了几个严重的问题,比如降低依赖类的可测试性,从而降低你的应用程序的可测试性。您还会造成潜在的内存泄漏(此
static
引用的所有*引用和资源将在整个应用程序生存期内保持活动状态。原因:一个static
引用被当作一个引用(又名对象)树的对象根。垃圾收集器不能收集static
对象树)。溶液
相反,使用IoC容器的生存期管理。例如,全局共享示例应该像其他依赖项一样注入。但是配置IoC容器以始终返回 * 相同 * 示例(共享示例)。对于大多数IoC容器,此生存期称为Singleton,如模式。
问题
你显式地创建示例。这种显式创建要求创建者知道所创建类型的所有依赖项。
在依赖注入上下文中,您不希望显式地创建示例。您的代码显示了缺点:
a)引入紧耦合(
new MyType()
)b)类声明了仅在内部构造其他类型时才需要的依赖项。那些创建的类型对于创建类的外部是不可见的(依赖项隐藏)
c)延展性损失:改变显式构造的类型或修改其依赖关系将需要修改创建类型。
溶液
解决方案是通过将依赖定义为类依赖来使依赖可见,换句话说,让IoC容器为您示例化类型。
如果需要动态示例化依赖关系,则必须使用 * Abstract Factory * 模式:
Func<T>
委托作为工厂。Func<T>
还允许传递动态参数,如用户输入数据: