我处于这种情况,我的服务接口由两个服务类实现。
例如,
IFooService
由 FooService
和 FooWithExtraInfoService
实施
这是界面:
public interface IFooService
{
Foo GetEntity(string fieldName, stringFieldValue);
}
这是 FooService
:
public class FooService: BarService, IFooService
{
public FooService(ILogService logservice): base(logservice)
{
}
public Foo GetEntity(string fieldName, string fieldValue)
{
//here goes the logic
}
}
这是 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";
}
}
正如您所看到的,一个选项可能是创建FooService的新对象,然后告诉unity注册IFooService
FooWithExtraInfoService
实现container.RegisterType<IFooService, FooWithExtraInfoService>();
的类型。
类似的东西:
FooService
但还有其他方法我不必创建//one possible option could be
var fooService = new FooService(logservice).GetEntity(fieldName, fieldValue)
//do additional stuff
的新对象吗?
FooWithExtraInfoService
让Unity以某种方式处理它?</ p>
或者我应该为Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.servlet.mvc.method.annotation.SseEmitter' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1466)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1097)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:589)
... 24 more
创建不同的界面吗?
我现在还不知道解决这个问题的最佳方法是什么。
任何建议都会有所帮助。
答案 0 :(得分:1)
这似乎是decorator pattern的好候选人。
装饰器模式包装现有服务,为其添加其他功能,而无需对其进行更改。这使您可以清楚地分离FooService
对FooWithExtraInfoService
所做的责任,并仍然允许DI容器提供“内部”实例。
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";
}
}
然后你只需要将你的DI容器连接起来,如:
var instance = new FooWithExtraInfoService(new FooService(new LogService()));
在Unity中,此注册可以像:
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")));
注意:您可以在this answer中使用基于约定的装饰器注册的示例。
与继承不同,装饰器与FooService
松散耦合。 ILogService
不需要仅传递给装饰器,因此可以将其转发到超类构造函数中。此外,只需更改DI配置,即可在FooWithExtraInfoService
和FooService
之间轻松添加另一个装饰器类。
var instance = new FooWithExtraInfoService(
new FooDecorator1(
new FooService(new Logger())));
答案 1 :(得分:0)
鉴于两者都继承自import React from 'react';
import { connect } from 'react-redux';
import { removeItem, selectItem } from '../actions/items';
import { Badge, ListGroup, ListGroupItem, Button } from 'reactstrap';
const stylesForActiveItem = {
borderLeft: '4px solid red',
transition: 'all .5s',
marginLeft: '-4px',
borderRadius: '0'
}
class Item extends React.Component {
constructor(props) {
super(props);
}
render() {
const { removeItem, selectItem, id, title, selected } = this.props;
return (
<ListGroup className="Item">
<ListGroupItem
onClick={() => selectItem({ id })}
className={selected ? 'Item__text active-item' :
'Item__text'}
>{title} <Badge className="Item__badge">14</Badge>
</ListGroupItem>
<Button className="Item__btn" onClick={() => removeItem({ id
})}>Delete</Button>
</ListGroup>
);
}
}
const mapDispatchToProps = (dispatch) => ({
removeItem: (id) => dispatch(removeItem(id)),
selectItem: (id) => dispatch(selectItem(id))
})
export default connect(null, mapDispatchToProps)(Item);
,创建一个实现接口的中间类型BarService
:
FooServiceBase
让public abstract class FooServiceBase : BarService, IFooService
{
public Foo GetEntity(string fieldName, string fieldValue)
{
//here goes the logic
}
}
和FooWithExtraInfoService
继承。
答案 2 :(得分:0)
我相信您的情况应该使用Composition
...意味着拥有FooService
类型的属性,而不是像下面那样,因为您只想使用GetEntity()
方法而无意扩展它
public class FooWithExtraInfoService: BarService
{
public FooService FooService { get; set; }
答案 3 :(得分:0)
当您无法单独依靠界面来定义服务消费者所需的行为时,另一种方法是为DI注册一个或两个具体实现。
然后,任何可以安全依赖于更简单的FooWithExtraInfoService
的类都可以声明对它的依赖,而那些你知道需要来自FooWithExtraInfoService
的附加功能的类可以依赖于它。 IFooService
甚至可以声明对{{1}}的依赖,以注入更简单的实现。
基本上,界面服务很有用,但在每种情况下都不要试图使用界面服务。
答案 4 :(得分:0)
FooWithExtraInfoService
似乎是FooService
,但有额外的信息,对吧?
那么,实际上使成为一个带有额外信息的FooService
类。在GetEntity
FooService
关键字中提供virtual
函数,并且可以在子类中重写它。然后,您可以在FooWithExtraInfoService
中使用新的覆盖,只需调用其父实现。
改编后的FooService
课程:
public class FooService: BarService, IFooService
{
public FooService(ILogService logservice): base(logservice)
{
}
public virtual Foo GetEntity(string fieldName, string fieldValue)
{
//here goes the logic
}
}
实施:
public class FooWithExtraInfoService: FooService
{
public FooWithExtraInfoService(ILogService logservice): base(logservice)
{
}
public override Foo GetEntity(string fieldName, string fieldValue)
{
Foo foo = base.GetEntity(fieldName, fieldValue)
//do additional stuff
foo.SomeField = "abc";
}
}