首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >利用控制器和视图中的继承

利用控制器和视图中的继承
EN

Stack Overflow用户
提问于 2018-09-12 06:18:00
回答 3查看 1.8K关注 0票数 13

不久前我在codereview.stackexchange.com上发布了this review ...我觉得它可能更适合stackoverflow,因为它更像是一个问题,而不是代码审查。

这需要一点解释,请容忍我,,__。

我正在开发一个电子商务网站在ASP.NET的MVC。用户可以在网站上发布不同类型的广告。

我正在使用继承来定义我的广告类型,这个问题是关于利用层次结构来删除控制器和视图中的重复代码。

我有不同的广告类型:SimpleAdCarRealEstateRental

每一个广告都是从AdBase派生出来的,它具有所有的共同属性:

代码语言:javascript
复制
public abstract class AdBase
{
    public long AdBaseId { get; set; }
    public bool IsActive { get; set; }
    public long UserId { get; set; }
    public string Title { get; set; }
    public short AdDurationInDays { get; set; }
    public string PhotosFolder { get; set; }
}

现在其他的广告都是从这个基类派生的:

代码语言:javascript
复制
public class SimpleAd : AdBase
{
    public decimal Price { get; set; }
}

public class Car : AdBase
{
    public decimal Price { get; set; }
    public string Make { get; set; }
}

public class RealEstateRental : AdBase
{
    public decimal WeeklyRent { get; set; }
    public DateTime AvailableFrom { get; set; }
    public short NoOfBedrooms { get; set; }
    public short NoOfBathrooms { get; set; }
}

我使用Entity Framework与数据库交互,并使用Unit of Work和Repository模式:

我有一个包含所有常见广告方法的通用AdBaseRepository:

代码语言:javascript
复制
public abstract class AdBaseRepository<TEntity> where TEntity : AdBase
{
    protected readonly ApplicationDbContext Context;

    public AdBaseRepository(ApplicationDbContext context)
    {
       Context = context; 
    }

    public TEntity Get(long adBaseId)
    {
        return Context.AdBase.OfType<TEntity>()
                  .Where(r => r.IsActive == true && r.AdBaseId == adBaseId)
                  .FirstOrDefault();
    }

    // more common methods here...
}

其他广告存储库继承自上面的类:

代码语言:javascript
复制
public class SimpleAdRepository : AdBaseRepository<SimpleAd>
{
    public SimpleAdRepository(ApplicationDbContext context) : base(context)
    {
    }
}

public class CarRepository : AdBaseRepository<Car>
{
    public CarRepository(ApplicationDbContext context) : base(context)
    {
    }

    // methods which apply only to car here...
}

这是我的工作单位:

代码语言:javascript
复制
public class UnitOfWork
{
    protected readonly ApplicationDbContext Context;

    public UnitOfWork(ApplicationDbContext context)
    {
        Context = context;
        SimpleAd = new SimpleAdRepository(Context);
        RealEstateRental = new RealEstateRentalRepository(Context);
        Car = new CarRepository(Context);
    }

    public SimpleAdRepository SimpleAd { get; private set; }
    public RealEstateRentalRepository RealEstateRental { get; private set; }
    public CarRepository Car { get; private set; }

    public int SaveChanges()
    {
        return Context.SaveChanges();
    }

    public void Dispose()
    {
        Context.Dispose();
    }
}

到目前为止我对一切都很满意...但问题是我不知道如何在我的控制器和视图中利用这种继承层次结构。

目前,我有3个控制器:SimpleAdControllerCarControllerRealEstateRentalController

代码语言:javascript
复制
public class SimpleAdController : ControllerBase
{
    private UnitOfWork _unitOfWork;

    public SimpleAdController(UnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    [HttpGet]
    // display specific ad
    public ActionResult Display(long id)
    {
        SimpleAd simpleAd = _unitOfWork.SimpleAd.Get(id);
        /* 
         * I have not included my ViewModel Classes in this question to keep
         * it small, but the ViewModels follow the same inheritance pattern
         */
        var simpleAdDetailsViewModel = Mapper.Map<SimpleAdDetailsViewModel>(simpleAd);
        return View(simpleAdDetailsViewModel);
    }
}

CarControllerRealEstateRentalController有相同的Display方法,除了广告的类型不同(例如在CarController中我有):

代码语言:javascript
复制
    public ActionResult Display(long id)
    {
        Car car = _unitOfWork.Car.Get(id);
        var carViewModel = Mapper.Map<CarViewModel>(car);
        return View(car);
    }

我想要实现的是创建一个AdBaseController,将所有常用方法放入其中,如下所示:

代码语言:javascript
复制
public class AdBaseController : ControllerBase
{
    private UnitOfWork _unitOfWork;

    public AdBaseController(UnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    // Display for generic ad type
    [HttpGet]
    public ActionResult Display(long id)
    {
        // SimpleAd simpleAd = _unitOfWork.SimpleAd.Get(id);
        /* 
         * I need to replace the above line with a generic ad type... 
         * something like: _unitOfWork<TAd>.GenericAdRepository.Get(id)
         */

        // var simpleAdDetailsViewModel = Mapper.Map<SimpleAdDetailsViewModel>(simpleAd);
        // return View(simpleAdDetailsViewModel);
        /* 
         * similarly I have to replace the above 2 lines with a generic type
         */
    }
}

如果我这样做,那么我的广告控制器可以继承它,我不需要在每个广告控制器中重复相同的显示方法……但是我需要让我的UnitOfWork泛型...或者有2个UoW (通用和非通用)...我不确定这是不是一个好主意?关于拥有 AdBaseController的任何建议

类似地,我在视图中重复了很多代码。例如,这是显示SimpleAdView

代码语言:javascript
复制
<div class="row">
    <div class="col-l">
        @*this partial view shows Ad photos and is common code for all ad types*@
        @Html.Partial("DisplayAd/_Photos", Model)
    </div>
    <div class="col-r">
        <div class="form-row">
            @*Common in all ads*@
            <h5>@Model.Title</h5>
        </div>

        @*showing ad specific fields here*@
        <div class="form-row">
            <h5 class="price">$@Model.Price</h5>
        </div>

        @*Ad heading is common among all ad types*@
        @Html.Partial("DisplayAd/_AdBaseHeading", Model)
    </div>
</div>
@*Ad Description is common among all ad types*@
@Html.Partial("DisplayAd/_Description", Model)

这是我的display CarView

代码语言:javascript
复制
<div class="row">
    <div class="col-l">
        @*Common in all ads*@
        @Html.Partial("DisplayAd/_Photos", Model)
    </div>
    <div class="col-r">
        <div class="form-row">
            @*Common in all ads*@
            <h5>@Model.Title</h5>
        </div>

       @*Price and Make are specific to Car*@ 
        <div class="form-row">
            <h5 class="price">$@Model.Price</h5>
        </div>
        <div class="form-row">
            <h5 class="make">@Model.Make</h5>
        </div>

        @*Common in all ads*@ 
        @Html.Partial("DisplayAd/_AdBaseHeading", Model)
    </div>
</div>
@*Common in all ads*@
@Html.Partial("DisplayAd/_Description", Model)

再一次,我感觉我在每个视图中重复了很多代码。我试图通过将它们放在公共的局部视图中来减少重复代码的数量。我不确定是否有更好的方法来做这件事?

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52284912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档