情况:
Assembly 1
________________________ ________________________
| Class A | | Class B |
|-----------------------| |-----------------------|
| Method someMethod |---------->| Method otherMethod |
| | | |
|_______________________| |_______________________|
程序集1是其他开发人员可以使用的应用程序。 我们只给他们.dll所以如果我们不改变api,我们可以从应用程序发布更新。开发人员无法更改程序集1中的框架
方法是虚拟的,因此开发人员可以覆盖方法,以便在需要时实现自己的逻辑。
问题是开发人员无法覆盖B类中的otherMethod, 他可以覆盖它,但是A类总是从B类调用方法而不是覆盖方法。
Assembly 1
________________________ ________________________
| Class A | | Class B |
|-----------------------| |-----------------------|
| Method someMethod |----XX---->| Method otherMethod |
| | | |
|_______________________| |_______________________|
\ |
\ |
\ |
Assembly 2 \ |
\ ________________|_______
\ | Class ExtendedB |
\ |-----------------------|
\____________>| Method otherMethod |
| |
|_______________________|
装配2具有对装配1的引用
部分类不起作用,因为它必须是相同的程序集,并且不能在2
上工作这个问题有设计模式吗? 或者是否有其他解决方案或反射?
编辑添加了一个代码示例:
/* ASSEMBLY 1 */
namespace Assembly1
{
public interface IAService
{
void TestMethod3();
void TestMethod4();
}
public interface IBService
{
void TestMethod1();
void TestMethod2();
}
public class AService : IAService
{
// Base implementation of AService
public virtual void TestMethod3()
{
//do something
}
public virtual void TestMethod4()
{
//do something
}
}
public class BService : IBService
{
// Base implementation of BService
public virtual void TestMethod1()
{
//do something
}
public virtual void TestMethod2()
{
//need to call AService implementation from assembly 2
}
}
}
/* ASSEMBLY 2 */
namespace Assembly2
{
public class NewAService : AService
{
public override void TestMethod3()
{
//default implementation which could be overridden
base.TestMethod3();
}
public override void TestMethod4()
{
//default implementation which could be overridden
//An implementation of IBService Should be called
base.TestMethod4();
}
}
}
答案 0 :(得分:4)
你应该重构
public interface IClassB
{
void SomeMethod();
}
public Class A
{
private IClassB myInstanceB = new ClassB();
public ClassA(){}
public ClassA(IClass B)
{
myInstanceB = B;
}
public void SomeMethod()
{
myInstanceB.SomeMethod();
}
}
public ClassB : IClassB
{
public void SomeMethod()
{
// some wicked code here...
}
}
完成这个重构后,开发人员可以使用空构造函数来使用默认实现。如果他们需要一些其他逻辑而不是他们只需要实现接口IClassB并将其传递给另一个构造函数。
程序集2中的用法将是这样的
public class NewFunctionalityClass : IClassB
{
public void SomeMethod()
{
//something else
}
}
public TestClass()
{
public void ShowMethod()
{
var defaultObject = new ClassA();
defaultObject.SomeMethod(); // default implementation
var otherObject = new ClassA(new NewFunctionalityClass());
otherObject.SomeMethod(); // here the new implementation will run
}
}
答案 1 :(得分:3)
假设A
调用通过ExtendedB
类型的变量引用的B
实例,并且该方法在virtual
中标记为B
, override
中的ExtendedB
,调用应该是多态的。它应该工作。也许你可以展示一些代码。
答案 2 :(得分:3)
在没有实际代码的情况下很难分辨,但是以面值来看你的图(顺便说一下,喜欢ASCII艺术!),我建议A类引用一个接口而不是硬编码到B级。
像这样:
// ----- this is in Assembly 1 -----------
public ClassA
{
public MyInterface myDependentObject;
}
public interface MyInterface
{
void OtherMethod();
}
public class ClassB : MyInterface
{
public void OtherMethod()
{
// some code here...
}
}
// ----- this is in Assembly 2 -----------
public class OtherB : MyInterface
{
public void OtherMethod()
{
// some code here...
}
}
在程序集2中,将OtherB分配给ClassA:
// ----- this is in Assembly 2 -----------
OtherB b = new OtherB();
ClassA a = new ClassA { myDependentObject = b };
现在,当ClassA执行myDependentObject.OtherMethod()
时,它将从程序集2而不是程序集1定义中获取。
... HTH
答案 3 :(得分:1)
您能提供一些示例的缩减代码吗?我很欣赏ascii艺术,但我怀疑问题可能在于A如何获得它所使用的B。如果它实例化它自己的副本,则它无法在派生类中调用重写方法。
那就是说,我也同意其他人建议的界面重构是要走的路。允许A从接口IB工作,因此它必须使用提供的IB实现者,而不是生成自己的实现者。这样,提供的对象是B,B的子类还是其他完全无关紧要。它还使A,B和Bs子类更易于测试,这是一件好事。
答案 4 :(得分:0)
您可能需要使用策略或模板模式来解决此问题。
答案 5 :(得分:0)
有几种设计模式可行。这是我在阅读你的帖子时想到的列表(按此顺序)。
ADAPTER
DECORATOR
TEMPLATE METHOD
。