假设我们的visual studio解决方案中有3个项目。项目A,B和C.
项目代码:
public class A
{
public void someMethodA()
{
B b = new B();
b.someMethodB(new C());
}
}
项目B代码:
public class B
{
public void someMethodB(C c)
{
c.foo(); // we do something with C, call C's method
}
}
项目C代码:
public class C
{
public void foo()
{
return; // just for testing
}
}
项目B根据需要引用项目C(someMethodB中需要C类)。项目A引用项目B,因为它创建新对象B并调用B的方法 - someMethodB()。
此时我们的解决方案将无法编译,因为项目A需要引用项目C - 它调用需要项目C的b.someMethodB(new C())。项目A是否真的需要引用项目C?不能从项目B获得它,它也引用它。我知道每个项目都会生成自己的dll文件,在bin目录中有3个文件,但它仍然可以从项目B中获得所需的文件。
项目C不是B域,但我们可以参考C到B。
答案 0 :(得分:1)
如果A只是在B上调用方法而不必传入C,即使该方法本身使用C,也不需要直接引用。但是,由于A需要构造C,因此需要直接引用C才能获得所需的元数据 - 此元数据包含在C中,不会复制到B。
如果从链接的所有引用库中复制了所有元数据,那么您只需要直接引用您正在使用的dll,即使从未使用过该函数,dll的大小也会膨胀 - 它需要在那里“以防万一”。
答案 1 :(得分:0)
为什么不在项目B中创建一个返回new C()
的方法?然后你可以避免在A中使用C.
答案 2 :(得分:0)
是的,A需要直接引用,因为它需要知道它正在处理什么类型的C
例如,可能有一个System.Whatever.C
和一个MyProject.C
- 现在,如果你没有指定它,它应该在new C()
调用什么构造函数?
如果你想避免在A中引用,你可以在someMethodB
中创建C的实例,而不是将其作为参数传递。
答案 3 :(得分:0)
如果您的C
程序集实现了某个接口(例如IC
),而程序集A
引用了定义接口的程序集,那么{{只要A
方法的返回类型不是具体的C
,而是接口B
,就不必了解C
的任何内容。
示意图,它应该是这样的:
这很可能是你应该如何组织你的应用程序。我注意到你提到传递某个IC
,其中包含数据库连接所需的信息,但你当然不希望从UI层访问数据库凭据,甚至不能创建实际的ConnectionInfo
个实例。
例如,您可以实现一种存储库模式,或者像这样的简单ORM:
DbConnection
您的// IC assembly (common assembly containing entities and repo interfaces)
public interface ISession : IDisposable
{
// It can even be an empty, marker interface for the
// outside world. Only `C` will know its internals anyway.
}
public interface IRepoFactory
{
ISession OpenSession();
IRepo<T> GetRepo<T>(ISession session);
}
程序集可以将具体的B
实例返回到Session
:
A
但是你的// B assembly
// RepoFactory should also be internal to B assembly,
// the only thing that A needs is a method which will
// provide the implementation of IRepoFactory
internal RepoFactory : IRepoFactory
{
public ISession OpenSession()
{
// this creates a concrete instance,
// but callers will only get the `ISession` interface
return C.CreateActualSession();
}
// other methods should also accept the session
// object through its interface
public IRepo<T> GetRepo<T>(ISession session)
{
return C.GetRepo(session);
}
}
程序集可以使用A
而不知道它是如何在幕后实现的:
ISession