关于c#:如何使用多个子对象.net实现继承

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);
    }
}

编辑单元测试您可以模拟传递的服务(因为它们有一个公共的抽象基类),并验证它们是否被您的新服务调用。这比单元测试更多的是交互测试,但它将确保调用正确的方法。如果新服务中没有预处理/后处理,则不需要对新服务进行任何进一步的测试。


使用类的.net不支持多重继承。只能从一个类继承,但可以实现任意多个接口。因此,可以用于实现多继承的机制是使用实现多个接口。

下面简单明了:

1
2
3
4
5
public class AuditService : BaseService
{ }

public class FooService : BaseService
{ }

现在,如果您想要一个类,即AuditServiceFooService拥有的所有teh服务,您可以声明一个接口,例如IUnionInterface,其中包含您想要的所有服务,然后您可以从类中请求实现IUnionInterface

1
2
public class SuperService : IUnionInterface
{ }

或者您可以声明一个包含AuditServiceFooServiceINonCommonFeatures的非公共特性的接口,然后让您的类从BaseService继承并实现INonCommonFeatures

1
2
public class SuperService : BaseService, INonCommonFeatures
{ }

现在您只需要实现INonCommonFeatures的特性。