解决多个接口实现问题 [英] Solving multiple interface implementation

查看:151
本文介绍了解决多个接口实现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我处于这种情况,我的服务接口由两个服务类实现。



例如,



IFooService FooService FooWithExtraInfoService



这是界面:

  public interface IFooService 
{
Foo GetEntity(string fieldName,stringFieldValue);
}

这是 FooService

 公共类FooService:BarService,IFooService 
{
public FooService (ILogService logservice):base(logservice)
{
}

public Foo GetEntity(string fieldName,string fieldValue)
{
//这里去逻辑
}
}

这是 FooWithExtraInfoService

  public class FooWithExtraInfoService:BarService,IFooService 
{
public FooWithExtraInfoService(ILogService logservice):base(logservice)
{
}

public Foo GetEntity(string fieldName,string fieldValue)
{
//一个可能的选项可能是
var foo = new FooService(logservice).GetEntity(fieldName,fieldValue)
//做额外的东西
foo.SomeField =abc;
}
}

正如你所看到的一个选项可能是创建新对象FooService然后告诉unity注册类型 IFooService FooWithExtraInfoService 实现。



类似于:

  container.RegisterType< IFooService,FooWithExtraInfoService>(); 

但还有其他方法我不必创建<$ c $的新对象c> FooService ?

  //一个可能的选项可能是
var fooService = new FooService(logservice)。GetEntity(fieldName,fieldValue)
//做额外的东西

和让Unity以某种方式处理它?<​​/ p>

或者我应该为创建不同的接口FooWithExtraInfoService



我不知道在这一点上解决这个问题的最佳方法是什么。



任何建议都会有所帮助。

解决方案

这似乎是装饰器模式



装饰器模式包装现有服务,为其添加其他功能而无需进行更改对它。这允许您从 FooWithExtraInfoService 中清楚地分离 FooService 所做的职责,并且仍允许DI容器提供内部 实例。

 公共类FooWithExtraInfoService:IFooService 
{
private readonly IFooService fooService;

public FooWithExtraInfoService(IFooService fooService)
{
if(fooService == null)
抛出新的ArgumentNullException(nameof(fooService));
this.fooService = fooService;
}

public Foo GetEntity(string fieldName,string fieldValue)
{
//调用IFooService的装饰实例
var foo = this.fooService .GetEntity(fieldName,fieldValue);
//做额外的东西
foo.SomeField =abc;
}
}

然后你只需要把你的DI连接起来容器如:

  var instance = new FooWithExtraInfoService(new FooService(new LogService())); 

在Unity中,此注册可以像:

  container.RegisterType< ILogService,LogService>(); 

//将FooService注册为命名服务
container.RegisterType< IFooService,FooService>(foo);

//注册FooWithExtraInfoService并将FooService注入其中
container.RegisterType< IFooService,FooWithExtraInfoService>(
new InjectionConstructor(new ResolvedParameter< IFooService>(foo)));




注意:您的示例可以使基于会议的装饰者注册在这个答案


与继承不同,装饰器松散耦合来自 FooService ILogService 不需要仅传递给装饰器,因此可以将其转发到超类构造函数中。此外,只需更改DI配置,即可轻松地在 FooWithExtraInfoService FooService 之间添加另一个装饰器类。

  var instance = new FooWithExtraInfoService(
new FooDecorator1(
new FooService(new Logger())));


I am in this situation where my service interface is being implemented by two service classes.

For example,

IFooService is implemented by FooService and FooWithExtraInfoService

Here is the interface:

public interface IFooService
{
    Foo GetEntity(string fieldName, stringFieldValue);
}

Here is FooService:

public class FooService: BarService,  IFooService
{
    public FooService(ILogService logservice): base(logservice)
    {
    }

    public Foo GetEntity(string fieldName, string fieldValue)
    {
        //here goes the logic
    }
}

Here is FooWithExtraInfoService:

public class FooWithExtraInfoService: BarService, IFooService
{
    public FooWithExtraInfoService(ILogService logservice): base(logservice)
    {
    }

    public Foo GetEntity(string fieldName, string fieldValue)
    {
        //one possible option could be
        var foo = new FooService(logservice).GetEntity(fieldName, fieldValue)
        //do additional stuff
        foo.SomeField = "abc";
    }
}

As you can see one option could be creating new object of FooService and then telling unity to register type where IFooService is implemented by FooWithExtraInfoService.

Something like:

container.RegisterType<IFooService, FooWithExtraInfoService>();

But is there some other way where I don't have to create new object of FooService?

//one possible option could be
var fooService = new FooService(logservice).GetEntity(fieldName, fieldValue)
//do additional stuff

And let Unity handle it somehow?

Or should I create different interface for FooWithExtraInfoService?

I don't know what is the best way to approach this problem at this point.

Any suggestions would be helpful.

解决方案

This seems like a good candidate for the decorator pattern.

The decorator pattern wraps the existing service, adding additional functionality to it without having to make changes to it. This allows you to cleanly separate responsibilities of what FooService does from FooWithExtraInfoService and still allow the DI container to provide the "inner" instance.

public class FooWithExtraInfoService : IFooService
{
    private readonly IFooService fooService;

    public FooWithExtraInfoService(IFooService fooService)
    {
        if (fooService == null)
            throw new ArgumentNullException(nameof(fooService));
        this.fooService = fooService;
    }

    public Foo GetEntity(string fieldName, string fieldValue)
    {
        // call the decorated instance of IFooService
        var foo = this.fooService.GetEntity(fieldName, fieldValue);
        //do additional stuff
        foo.SomeField = "abc";
    }
}

Then you just need to wire it up with your DI container like:

var instance = new FooWithExtraInfoService(new FooService(new LogService()));

In Unity, this registration could be done like:

container.RegisterType<ILogService, LogService>();

// Register FooService as a named service
container.RegisterType<IFooService, FooService>("foo");

// Register FooWithExtraInfoService and inject FooService into it
container.RegisterType<IFooService, FooWithExtraInfoService>(
    new InjectionConstructor(new ResolvedParameter<IFooService>("foo")));

NOTE: An example of how you could make decorator registrations convention-based is in this answer.

Unlike using inheritance, the decorator is loosely coupled from FooService. The ILogService does not need to be passed into the decorator only so it can be forwarded into the superclass constructor. Additionally, you can easily add another decorator class between FooWithExtraInfoService and FooService simply by changing the DI configuration.

var instance = new FooWithExtraInfoService(
    new FooDecorator1(
    new FooService(new Logger())));

这篇关于解决多个接口实现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆