首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用SimpleInjector (使用Tridion)将WCF服务重新创建为单例实例

如何使用SimpleInjector (使用Tridion)将WCF服务重新创建为单例实例
EN

Stack Overflow用户
提问于 2017-10-09 18:01:03
回答 1查看 554关注 0票数 2

我使用的是IoC容器SimpleInjector。我知道不应该重新创建单例,因为这不是它们的目的,但是我的问题是WCF,当它进入故障状态时,根据几个读取,它无法被恢复,需要创建一个新的实例。

我有一个名为CoreServiceService的类,它使用两个WCF服务。

  1. CoreService
  2. ECLService

我希望这些服务是单例的,因为我将对CoreServiceSession进行大量调用,而创建那些WCF服务成本太高,花费了很多时间,在创建之后,它们的速度要快得多。

我是这样注册的:

代码语言:javascript
运行
复制
container.Register(() => new SessionAwareEclServiceClient(binding, eclServiceRemoteAddress), Lifestyle.Singleton);

container.Register(() => new SessionAwareCoreServiceClient(binding, coreServiceRemoteAddress), Lifestyle.Singleton);

container.Register(typeof(ICoreServiceSession), typeof(CoreServiceSession), Lifestyle.Scoped);

我的问题是,在使用ECLService时,如果无法检索某些内容,则进入错误的连接,在这种情况下,我调用.Abort()并关闭连接。但是下一次我调用我的服务时,ECLService WCF服务仍然处于Faulted状态(因为它是单例的),所以我需要一种重新创建连接的方法。

我试过这样的方法:

代码语言:javascript
运行
复制
coreServiceSession.EclServiceClient = (SessionAwareEclServiceClient)container.GetInstance(typeof(SessionAwareEclServiceClient));

但是,当然,它给了我同样的例子。

我还尝试使用这个初始化器:

代码语言:javascript
运行
复制
container.RegisterInitializer<ICoreServiceSession>(coreServiceSession =>
{
    if (coreServiceSession.EclServiceClient.State == CommunicationState.Faulted)
    {
        coreServiceSession.EclServiceClient.Abort();
        coreServiceSession.EclServiceClient = null;
        coreServiceSession.EclServiceClient = (SessionAwareEclServiceClient)container.GetInstance(typeof(SessionAwareEclServiceClient));
    }
}

同样的事情,我尝试使用而不是container.GetInstance,这是:

代码语言:javascript
运行
复制
coreServiceSession.EclServiceClient = new SessionAwareEclServiceClient(binding, eclServiceRemoteAddress);

同样的事情。有什么想法/选择吗?

在这种情况下,有没有办法强制获得一个新实例?

更新

这是类CoreServiceSession的一部分。

代码语言:javascript
运行
复制
public class CoreServiceSession : ICoreServiceSession
{
    public CoreServiceSession(ISessionAwareCoreService sessionAwareEclServiceClient, SessionAwareCoreServiceClient sessionAwareCoreServiceClient)
    {
        EclServiceClient = sessionAwareEclServiceClient;
        CoreServiceClient = sessionAwareCoreServiceClient;
    }

    public ISessionAwareCoreService EclServiceClient { get; set; }

    public SessionAwareCoreServiceClient CoreServiceClient { get; set; }

    public string CreateOrGetStubUris(string eclItemUri)
    {
        var stubInfo = EclServiceClient.CreateOrGetStubUris(new List<string> { eclItemUri }).FirstOrDefault();
    }
}

提前谢谢。吉列尔莫

EN

回答 1

Stack Overflow用户

发布于 2017-10-10 07:45:56

@ScottHannen在他的评论中已经给出了答案:不要将频道注册为单身汉:它们创建起来并不昂贵,只有频道工厂才是。

事实上,您根本不应该将WCF客户端对象注入构造函数。将它们注入构造函数意味着它们是一个有用的抽象,可用于拦截、模拟或替换,而使用此类客户端的类通常强耦合到WCF。

因此,与其将它们注入构造函数,不如让使用者使用ChannelFactory在内部创建它们。即使这样的ChannelFactory通常不需要注入,您也可以在私有静态字段中更新它。

这就是您的CoreServiceSession的样子:

代码语言:javascript
运行
复制
public class CoreServiceSession : ICoreServiceSession
{
    private static readonly ChannelFactory factory =
        new ChannelFactory<ISessionAwareCoreService>(myBinding, myEndpoint);

    public string CreateOrGetStubUris(string eclItemUri)
    {
        var client = factory.CreateChannel();

        try
        {
            return EclServiceClient.CreateOrGetStubUris(
                new List<string> { eclItemUri }).FirstOrDefault();
        }
        finally
        {
            try
            {
                ((IDisposable)client).Dispose();
            }
            catch
            {
                // We need to swallow exceptions thrown by Dispose. 
                // See: https://marcgravell.blogspot.com/2008/11/dontdontuse-using.html
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46652410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档