如何干掉.NET Web表单包装器



>大量编辑:

因此,我将后面的 ASP.NET 代码重构为表示器进行单元测试。完成此操作后,我注意到我为允许这样做而制作的包装器有很多我想消除的重复项。我的想法是使用类继承来抽象这种重复,但我无法弄清楚。我目前拥有的一个例子:

[TestFixture]
public class PresenterTests
{
    [Test]
    public void TestMethodTest()
    {
        var fooMock = Mock<IFooWrapper>();
        var fooMock2 = Mock<IFooWrapper>();
        var barMock = Mock<IBarWrapper>();
        var barMock2 = Mock<IBarWrapper>();
        fooMock.Setup(x => x.Baz()).Returns(fooMock2);
        barMock.Setup(x => x.Baz()).Returns(bazMock2);
    }
}
public interface IFooWrapper
{
    IFooWrapper Baz();
}
public class FooWrapper : IFooWrapper
{
    private Foo _instance;
    public FooWrapper(Foo instance)
    {
        _instance = instance;
    }
    public IFooWrapper Baz()
    {
        return new FooWrapper(_instance);
    }
}
public interface IBarWrapper
{
    void Baz();
}
public class BarWrapper : IBarWrapper
{
    private Bar _instance;
    public BarWrapper(Bar instance)
    {
        _instance = instance;
    }
    public IBarWrapper Baz()
    {
        return new BarWrapper(_instance);
    }
}

根据史蒂夫哈里斯在下面所说的基于我非常糟糕的沟通,我目前有以下内容似乎很接近但并不完全存在:

public interface IBaseWrapper<TWrapper, T> where TWrapper: IBaseWrapper<TWrapper, T> where T : class
{
    TWrapper Baz();
}
public class BaseWrapper<TWrapper, T> : IBaseWrapper<TWrapper, T> where TWrapper : BaseWrapper<TWrapper, T> where T : class
{
    public T Instance;
    public BaseWrapper()
    {
    }
    public BaseWrapper(T instance)
    {
        Instance = instance;
    }
    public TWrapper Baz()
    {
        return new TWrapper(Instance);
    }
}
public interface IFooWrapper : IBaseWrapper<FooWrapper, Foo>
{
}
public class FooWrapper : BaseWrapper<FooWrapper, Foo>, IFooWrapper
{
    public FooWrapper() {}
    public FooWrapper(T instance) : base(instance) {}
}
public interface IBarWrapper : IBaseWrapper<BarWrapper, Bar>
{
}
public class BarWrapper : BaseWrapper<BarWrapper, Bar>, IBarWrapper
{
    public BarWrapper() {}
    public BarWrapper(T instance) : base(instance) {}
}

这些是您要查找的约束吗?

public interface IBaseWrapper<TWrapper, T> where TWrapper : IBaseWrapper<TWrapper, T>
{
    TWrapper Baz();
}
public class BaseWrapper<TWrapper, T> : IBaseWrapper<TWrapper, T> where TWrapper : BaseWrapper<TWrapper, T> where T : class
{
    private T _instance;
    public BaseWrapper(T instance)
    {
        _instance = instance;
    }
    public TWrapper Baz()
    {
        // note whatever wrapper class you are using must have a
        // constructor matching this base class
        return Activator.CreateInstance(GetType(), new object[] { _instance });
    }
}
public class Foo
{
    public void FooSpecificMethod()
    {
        // foo stuff
    }
}
public interface IFooWrapper<TWrapper> : IBaseWrapper<TWrapper, Foo> where TWrapper : IBaseWrapper<TWrapper, Foo>
{
    void FooSpecificMethod();
}
public class FooWrapper : BaseWrapper<FooWrapper, Foo>, IFooWrapper<FooWrapper>
{
    public FooWrapper(Foo instance) : base(instance)
    {
    }
    public void FooSpecificMethod()
    {
        instance.FooSpecificMethod();
    }
}

您可能使用工厂方法实现。

public class BaseWrapper
{
    public virtual void Baz()
    {
       // Do some shared work
    }
}
public class BarWrapper : BaseWrapper
{
    private Bar _instance;
    public BarWrapper(Bar instance)
    {
        _instance = instance;
    }
    public override void Baz()
    {
        base.Baz();
        // Do custom stuff for this wrapper type?
    }
}

当我尝试构建一段代码时,我通常以泛型实现为主导,该代码可以处理对继承共享接口公共类 IFileParser 的对象集合进行处理,其中 IFileImplementation 可以是各种东西。

希望这有帮助!

从您的示例代码来看,泛型似乎不是必需的。 不过,您可能正在实现装饰器模式。

此示例演示了代码的非泛型版本。 这就是你所追求的吗?

public interface IBazzer
{
    void Baz();
}
public class TheBaz : IBazzer
{
    public void Baz()
    {
        Console.WriteLine("Hello World");
    }
}
public class Wrapper : IBazzer
{
    private IBazzer _instance;
    public Wrapper(IBazzer instance)
    {
        _instance = instance;
    }
    public void Baz()
    {
        // do stuff before calling the wrapped Bazzer
        this.PreBaz();
        _instance.Baz();
        // do stuff after calling the wrapped Bazzer        
        this.PostBaz();
    }
    protected virtual void PreBaz(){}
    protected virtual void PostBaz(){}
}
public class FooWrapper : Wrapper
{
    public FooWrapper(IBazzer wrapped):base(wrapped){}
    protected override void PreBaz()
    {
        Console.WriteLine("Foo Pre Baz");
    }
    protected override void PostBaz()
    {
        Console.WriteLine("Foo Post Baz");
    }
}
public class BarWrapper : Wrapper
{
    public BarWrapper(IBazzer wrapped):base(wrapped){}
    protected override void PreBaz()
    {
        Console.WriteLine("Bar Pre Baz");
    }
    protected override void PostBaz()
    {
        Console.WriteLine("Bar Post Baz");
    }
}
void Main()
{
    var x = new     TheBaz();
    var y = new FooWrapper(x);
    y.Baz(); 
    // Foo Pre Baz
    // Hello World
    // Foo Post Baz
}

最新更新