How to implement inheritance with multiple sub objects .net
假设我有一个名为baseservice的基类,然后我有另一个名为auditservice的类,它继承自baseservice,也许我还有另一个名为fooservice的类,它也继承自baseservice。
所以层级结构是这样的
1 2 3 4 5 | BaseService | ---- AuditService | ---- FooService |
现在,如果我需要一个包含auditservice和fooservice的所有特性的新服务呢?
C不允许您从多个对象继承,那么我该怎么做呢?
我不想从1服务继承并重新编码所有其他项。
编辑:
要包含关于我的类的更多详细信息,请参阅下面的一些代码。
如您所见,我将覆盖foo服务和auditable服务中基本服务的特定函数。将来,我需要一个实现baseservice、foo service和auditable service所有功能的服务。
基本服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 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(); } } |
号
可审计服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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); } } } |
餐饮服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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); } } } |
。
正如@christos所说,在.NET中没有多个互调支持-您必须描述您的意图,以获得适合您需要的解决方案。
组合可以是一个解决方案,例如,创建另一个从BaseService派生的类,该类包含对AutidService的引用,并创建一个FooService实例来将操作委托给它们(如果BaseService已经为您的新服务提供了一个良好的接口,那么这将是一个解决方案)。好处可能是,您可以像使用装饰器模式一样控制委托,这可能是遵循SRP(单一责任原则)的干净餐厅。
提供有关新服务应如何重新使用定义的服务的详细信息…
您添加的代码非常适合组合,因为BaseService定义了具体服务提供的所有方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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); } } |
。
编辑单元测试您可以模拟传递的服务(因为它们有一个公共的抽象基类),并验证它们是否被您的新服务调用。这比单元测试更多的是交互测试,但它将确保调用正确的方法。如果新服务中没有预处理/后处理,则不需要对新服务进行任何进一步的测试。
使用类的
下面简单明了:
1 2 3 4 5 | public class AuditService : BaseService { } public class FooService : BaseService { } |
现在,如果您想要一个类,即
1 2 | public class SuperService : IUnionInterface { } |
号
或者您可以声明一个包含
1 2 | public class SuperService : BaseService, INonCommonFeatures { } |
现在您只需要实现