这个问题跟我之前提到的问题非常接近,但我不认为它们是相同的,所以认为将它们拆分是明智的(当你听到这个问题时这有点讽刺)。
我有一个分为两个项目的Web应用程序:
1)ASP.NET站点 2)包含业务对象,逻辑层方法和DAL方法的DLL。它们分成不同的命名空间但都在同一个DLL中。
我越是看着它并扩展了发展,我就意识到自己走错了路。我想把它们拆分成单独的DLL,以便我可以清楚地分离职责。
一旦我将代码放在不同的DLL中,我意识到很多类都相互调用。例如,当在DAL中创建客户端列表对象时,它还将调用companyDAL.cs并获取客户端所属的公司列表。所以我现在有两个直接相互引用的类。这似乎是一件相当糟糕的事情!它闻起来很糟糕,但我坚持下去,并尽力将事情分开。
为此,我将所有对象都带到接口,并将对它们的所有引用更改为接口。
我希望使用某种DI(目前只是了解它)所以对于每个对象,我创建了一个构造函数,为该DLL接受了一个Factory,(这个工厂将创建每个对象的新实例)班级可能要求)。我还设置了一个默认构造函数,它将使用默认的Factory调用DI构造函数,以确保始终使用一个工厂。
这一切都编译好所以我给了它一个旋转并获得了stackoverflow!这是我完全意识到,如果我有两个需要彼此的类,你就无法在没有另一个的情况下实例化。
Factory
{
IClient CreateNewIClient()
{
return new Client();
}
ICompany CreateNeIwCompany()
{
return new Company();
}
}
Client
{
private ICompany _company;
public Client() : this (new Factory()) {}
public Client(Factory factory)
{
_company = factory.CreateNewICompany();
}
public Client GetClientbyID(int id)
{
.... do stuff to get client from db
... got client object and companyid from db.
client.Company = _company.GetCompanybyID(companyid);
return client;
}
}
Company
{
private IClient _client;
public Company() : this (new Factory()) {}
public Company(Factory factory)
{
_client = factory.CreateNewIClient();
}
public Company GetCompanyWithAllClients(int companyid)
{
.... do stuff to get a company out and client ids
.... for each client id found
company.Clients.add(_client.GetClientByID(clientid));
return company;
}
}
我说DI的事情都错了,工厂的想法好吗?
我应该如何避免彼此需要的课程?他们此刻的原因是避免重复编码。我确信我可以编写更清晰的SQL来一次性完成所有工作,或者至少在同一方法中的几个查询中,但我试图避免在不同的地方重复代码。
感谢您提出的所有建议。
答案 0 :(得分:1)
这不是解决问题的答案。我认为你的工厂有些复杂(因为你得到了一个堆栈溢出异常而不能完全编译)。
问题是循环依赖。如果没有B实例,则无法实例化A,并且如果没有A实例,则无法实例化B实例。
public class Company : ICompany
{
private IClient _client;
// OK so first build a client and pass it in
public Company(IClient client)
{
_client = _client;
}
}
public class Client : IClient
{
private ICompany _company;
// OK so first build a company and pass it in. Oh. I can't... :(
public Client(ICompany company)
{
_company = company;
}
}
Misko有一篇关于此的文章可能有一些用处: http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/
基本上:你的班级设计是问题,需要修复。工厂只是混淆了这个问题:)
答案 1 :(得分:0)
也许你可以为你使用一些ORM工具DAL,比如NHibernate或Linq to SQL? NHibernate会将您的数据映射到具有双向链接的对象(如果需要)。
编辑:拼写错误
干杯, 韩国