C#Asp.Net MVC在接口上继承抽象类方法

时间:2018-08-06 19:02:04

标签: c# asp.net-mvc inheritance abstract-class autofac

我有一个抽象类,一个接口和一个继承了抽象类和接口的类。

我想从继承类的抽象类中公开该方法。我该如何实现?

public abstract class CustomerServiceBase
{
    public string GetName()
    {
        return "John Doe";
    }
}

public interface ICustomerService
{
    void DoOtherStuff();
}

public class CustomerService : CustomerServiceBase, ICustomerService
{
    public void DoOtherStuff()
    {
        //Code removed for brevity
    }
}

public class Start
{
    public void Go()
    {
        ICustomerService _customerService = new CustomerService();
        _customerService.DoOtherStuff();
        var name = _customerService.GetName();//This won't compile
    }
}

更新

道歉,我添加了准确显示这种情况的其他代码,即使用Autofac将依赖项注入到Asp.Net MVC控制器中,然后使用服务类来执行任务。

public abstract class CustomerServiceBase
{
    public string GetName()
    {
        return "John Doe";
    }
}

public interface ICustomerService
{
    void DoOtherStuff();
}

public class CustomerService : CustomerServiceBase, ICustomerService
{
    public void DoOtherStuff()
    {
        //Code removed for brevity
    }
}

public static class AutofacConfig
{
    public static IContainer Register(IAppBuilder app)
    {
        var builder = new ContainerBuilder();

        ConfigureServices(builder);

        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        SetBothDependencyResolvers(container);

        return container;
    }

    public static void ConfigureServices(ContainerBuilder builder)
    {
        builder.RegisterType<CustomerService>().AsImplementedInterfaces().InstancePerLifetimeScope();
    }

}

public class CustomerController : Controller
{
    protected readonly ICustomerService _customerService;

    public CustomerController(ICustomerService customerService)
    {
        this._customerService = customerService;
    }

    public ActionResult Index()
    {
        _customerService.DoOtherStuff();
        var name = _customerService.GetName();

        return View();
    }
}

结果(基于接受的答案)

public abstract class CustomerServiceBase : ICustomerService
{
    public abstract void DoOtherStuff();

    //You could mark this as virtual if you want the option to override functionality
    public string GetName()
    {
        return "John Doe";
    }
}

public interface ICustomerService
{
    void DoOtherStuff();
    string GetName();
}

public class CustomerService : CustomerServiceBase
{
    public override void DoOtherStuff()
    {
        //Code removed for brevity
    }
}

public class CustomerController : Controller
{
    protected readonly ICustomerService _customerService;

    public CustomerController(ICustomerService customerService)
    {
        this._customerService = customerService;
    }

    public ActionResult Index()
    {
        _customerService.DoOtherStuff();
        var name = _customerService.GetName();

        return View();
    }
}

5 个答案:

答案 0 :(得分:3)

只需更改变量的类型。自该类实现以来,您仍然可以调用ICustomerService的成员。

public void Go()
{
    CustomerService _customerService = new CustomerService();
    _customerService.DoOtherStuff();
    var name = _customerService.GetName();
}

答案 1 :(得分:1)

  

我想从继承类的抽象类中公开该方法。我该如何实现?

这已经发生。出现编译器错误的原因是您拥有的代码将_customerService指定为类型(接口)ICustomerService,并且此接口没有方法DoOtherStuff()的定义。如果要使用类型CustomerService,则可以调用在此类型继承的抽象类(或它实现的接口)上定义的方法。

CustomerService _customerService = new CustomerService();
_customerService.DoOtherStuff();
var name = _customerService.GetName(); // compiles just fine

关于问题的标题:

  

在接口上继承抽象类方法

这是不可能的(在c#中)。接口可以扩展其他接口并由类实现,但是一个接口不能“继承”另一个接口以外的任何东西(尽管公认的本地语言正在“扩展”一个接口)。

答案 2 :(得分:1)

您的问题源于您的_customerService变量为ICustomerService类型的事实。您的界面对抽象类一无所知。如果您希望该类型的东西具有特定的方法,则需要将其添加到您的界面中:

public interface ICustomerService
{
    void DoOtherStuff();
    string GetName();
}

然后,我将使您的抽象类实现成为接口,而不是您的CustomerService类。您还需要在抽象类中添加一个abstract方法,以便强制继承自抽象CustomerServiceBase的所有类添加一个DoOtherStuff()实现(您的抽象类不必添加自己的实现):

public abstract class CustomerServiceBase : ICustomerService
{
    //abstract forces any inheriting class to implement 'DoOtherStuff' there
    public abstract void DoOtherStuff();

    //You could mark this as virtual if you want the option to override functionality
    public string GetName()
    {
        return "John Doe";
    }
}

CustomerService应该是:

public class CustomerService : CustomerServiceBase

一旦这样做,您的Index()方法就可以了:

public ActionResult Index()
{
    //DoOtherStuff() and GetName() are both part of the interface now
    _customerService.DoOtherStuff();
    var name = _customerService.GetName();

    return View();
}

答案 3 :(得分:0)

CustomerService方法中使用ICustomerService代替Go

CustomerService _customerService = new CustomerService();
_customerService.DoOtherStuff();
var name = _customerService.GetName(); // Compiles now

答案 4 :(得分:0)

您进行ICustomerService _customerService时 您正在启动ICustomerService合同,并且该合同没有名为GetName()

的任何内容

因此,您可以通过放置GetName()获得合同,或者如上所述创建CustomerService本身。

另外,抽象类的整体思想是交互,因此,基本上,当您将CustomerService定义为非抽象类时,可以很好地使用

CustomerService customerService = new CustomerService

但是,CustomerServicePhoneService并不是TextService更好的命名方式,因为这些是客户在现实生活中将直接与之交互的东西。并且使用CustomerService本身而不是CustomerServiceBase,因为人们将直接使用客户服务,但不会以上述电话或短信或其他服务的形式使用客户服务。

public abstract class CustomerService {} <-- Think in real life this doesnt have interaction
public class PhoneService() {} <-- This interacts directly