假设我有一个名为BaseService的基类,那么我有另一个名为AuditService的类,它继承自BaseService,也许还有另一个名为FooService的类,它也继承自BaseService。
所以层次结构看起来像这样
BaseService
|
---- AuditService
|
---- FooService
现在如果我需要一个包含AuditService和FooService的所有功能的新服务呢?
c#不允许你从多个对象继承,所以我该怎么做呢?
我不想继承1项服务,并重新编码其余所有项目。
编辑:
要包含有关我的课程的更多详细信息,请参阅下面的代码。
正如您所看到的,我在foo服务和可审计服务中覆盖了基本服务的特定功能。将来我需要一个服务来实现baseservice,foo服务和可审计服务的所有功能。
BASESERVICE
public abstract class BaseService<TEntity>
where TEntity : class, IBaseEntity
{
protected DataContext _context;
protected BaseService(DataContext context)
{
_context = context;
}
public virtual async Task<ICollection<TEntity>> GetAllAsync()
{
return await _context.Set<TEntity>().ToListAsync();
}
public virtual Task<TEntity> GetAsync(long id)
{
return _context.Set<TEntity>().FindAsync(id);
}
public virtual Task<int> AddAsync(TEntity t)
{
if (_context.Entry(t).State == EntityState.Detached)
{
_context.Set<TEntity>().Add(t);
}
_context.Entry(t).State = EntityState.Added;
return _context.SaveChangesAsync();
}
public virtual Task<int> AddAllAsync(ICollection<TEntity> all)
{
foreach (var item in all)
{
if (_context.Entry(item).State == EntityState.Detached)
{
_context.Set<TEntity>().Add(item);
}
_context.Entry(item).State = EntityState.Added;
}
return _context.SaveChangesAsync();
}
public virtual Task<int> UpdateAsync(TEntity updated)
{
_context.Entry(updated).State = EntityState.Modified;
return _context.SaveChangesAsync();
}
public virtual async Task<int> DeleteAsync(long key)
{
TEntity entity = await GetAsync(key);
_context.Entry(entity).State = EntityState.Deleted;
return await _context.SaveChangesAsync();
}
public virtual Task<int> DeleteAsync(TEntity t)
{
_context.Entry(t).State = EntityState.Deleted;
return _context.SaveChangesAsync();
}
}
AUDITABLESERVICE
public class AuditableService<TEntity> : BaseService<TEntity>
where TEntity : class, IAuditableEntity
{
public virtual override Task<int> DeleteAsync(long key)
{
return DeleteAsync(key, true);
}
public virtual async Task<int> DeleteAsync(long key, bool useFlag)
{
TEntity entity = await GetAsync(key);
return await DeleteAsync(entity, useFlag);
}
public virtual override Task<int> DeleteAsync(TEntity t)
{
return DeleteAsync(t, true);
}
public virtual Task<int> DeleteAsync(TEntity t, bool useFlag)
{
if (useFlag)
{
// flag item as deleted
t.IsDeleted = true;
return UpdateAsync(t);
}
else
{
return base.DeleteAsync(t);
}
}
}
FooService接口
public class FooService<TEntity> : BaseService<TEntity>
where TEntity : class, IBaseEntity
{
protected IValidator<TEntity> _validator;
protected ValidatorService(DataContext context)
: base(context)
{
}
public override async Task<int> AddAsync(TEntity t)
{
var results = await _validator.ValidateAsync(t);
if (results.IsValid)
{
return await base.AddAsync(t);
}
else
{
throw new ValidationException(results.Errors);
}
}
public override async Task<int> UpdateAsync(TEntity updated)
{
var results = await _validator.ValidateAsync(updated);
if (results.IsValid)
{
return await base.UpdateAsync(updated);
}
else
{
throw new ValidationException(results.Errors);
}
}
}
答案 0 :(得分:2)
正如@Christos所说,.net中没有多重干预支持 - 您必须描述您的意图,以获得符合您需求的解决方案。
组合物可以是解决方案,例如创建另一个派生自BaseService的类,该类保存对AutidService的引用和FooService实例,以便将操作委托给它们(如果BaseService已经为您的新服务提供了良好的接口,那么这将是一个解决方案。可能的好处是,您可以控制委派就像装饰模式一样,这可能是遵循SRP(单一责任原则)的干净灵魂。)
向我们提供有关新服务如何重新使用已定义服务的更多信息......
由于BaseService定义了您的具体服务提供的所有方法,因此您添加的代码非常适合于合成:
public class NewService<T> : BaseService<T>
{
private readonly FooService<T> _fooService;
private readonly AuditableService<T> _auditableService;
public NewService (AuditableService<T> auditableService, FooService<T> fooService)
{
if(auditableService == null)
throw new ArgumentNullException("auditableService ");
if(fooService == null)
throw new ArgumentNullException("fooService");
_auditableService = auditableService;
_fooService = fooService;
}
public override Task<int> AddAsync(T t)
{
return _fooService.UpdateAsync(t);
}
public override Task<int> DeleteAsync(T t)
{
return _auditableService.DeleteAsync(t);
}
}
编辑UnitTesting 您可以模拟传递的服务(因为它们具有共同的抽象基类)并验证它们是否由您的新服务调用。这比单元测试更多的交互测试,但它将确保您调用正确的方法。如果新服务中没有预处理/后处理,则您不需要对新服务进行任何进一步测试。
答案 1 :(得分:1)
使用类.net
不支持多重继承。您只能从一个类继承,但可以根据需要实现任意数量的接口。因此,可用于实现多重继承的机制是使用实现多个接口。
以下内容很简单:
public class AuditService : BaseService
{ }
public class FooService : BaseService
{ }
现在,如果您想要AuditService
和FooService
所拥有的所有服务类,您可以声明一个接口,例如: IUnionInterface
,其中包含您想要的所有内容,然后您可以从您的班级中提出IUnionInterface
public class SuperService : IUnionInterface
{ }
或者您可以声明包含AuditService
和FooService
,INonCommonFeatures
的非常见功能的界面,然后让您的类继承自BaseService
并实现{{ 1}}。
INonCommonFeatures
现在您只需要实现public class SuperService : BaseService, INonCommonFeatures
{ }
。