【问题标题】:WCF Proxy + DI (Ninject) + IDisposableWCF 代理 + DI (Ninject) + IDisposable
【发布时间】:2014-11-21 19:27:41
【问题描述】:

我有一个调用一些 WCF 服务的 MVC4 应用程序。

我了解到使用“使用”语法 (read this...) 处理 WCF 代理时可能发生的一些问题。 我正在尝试在我的解决方案中正确实施 WCF 代理处理 (...and now this)。

一个标准的请求会在应用程序中运行以下层:

MVC 控制器 > “Main Facade” > “Minor Facades” > WCF 代理(遗留代码。不是我的错)

我正在使用 Ninject 3.2.2.0 将依赖项自动注入这些层。例如:

控制器:

public class HomeController : Controller
{
    private readonly SomeMainFacade _someMainFacade;

    public HomeController(SomeMainFacade someMainFacade)
    {
        _someMainFacade = someMainFacade;
    }
    ...
}

“主立面”:

public class SomeMainFacade 
{
    private readonly MinorFacade1 _minorFacade1;
    private readonly MinorFacade2 _minorFacade2;

     public SomeMainFacade (
        MinorFacade1 minorFacade1,
        MinorFacade2 minorFacade2
       ){
             _minorFacade1 = minorFacade1;
             _minorFacade2= minorFacade2;
        }
        ...
 }

“小立面”

public class MinorFacade1
{
    private readonly IWCFService _wcfServiceClient;

    public MinorFacade1(IWCFService wcfServiceClient)
    {
        _wcfServiceClient= wcfServiceClient;
    }
    ...
}

我想妥善处理“次要外观”中使用的 WCF 服务,但如果不进行大的重构,我想不出办法。也许 Ninject 会来救援...

感谢任何帮助。

谢谢。

【问题讨论】:

    标签: c# wcf asp.net-mvc-4 ninject


    【解决方案1】:

    这是我很久以前在遥远的星系中写的一门课:

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RemotingClient<T> : IDisposable
    {
        private bool _disposed;
    
        private readonly ChannelFactory<T> _factory;
    
    
        /// <summary>
        /// 
        /// </summary>
        public event OnCloseChannel ChannelClosed;
    
        public event OnFaultedChannel ChannelFaulted;
    
        /// <summary>
        /// 
        /// </summary>
        public delegate void OnCloseChannel();
    
        public delegate void OnFaultedChannel();
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="factory"></param>
        public RemotingClient(ChannelFactory<T> factory)
            : this(factory, SynchronizationContext.Current)
        {
        }
    
        private void OnClose(object sender, EventArgs e)
        {
            if (null != ChannelClosed)
                ChannelClosed();
        }
    
        private void OnFaulted(object sender, EventArgs e)
        {
            if (null != ChannelFaulted)
                ChannelFaulted();
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="context"></param>
        public RemotingClient(ChannelFactory<T> factory, SynchronizationContext context)
        {
            Context = context;
            _factory = factory;
            CreateNewChannel();
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uiCallback"></param>
        public void PostToContext(SendOrPostCallback uiCallback)
        {
    
            Context.Post(uiCallback, null);
        }
    
        public void CreateNewChannel()
        {
            Channel = _factory.CreateChannel();
    
            ICommunicationObject c = Channel as ICommunicationObject;
    
            if (null == c)
                throw new ArgumentException(
                    typeof(T) + " Can not be used as an ICommunicationObject");
    
            c.Closed += OnClose;
            c.Faulted += OnFaulted;
            c.Open();
        }
    
        /// <summary>
        /// 
        /// </summary>
        public SynchronizationContext Context
        { get; private set; }
    
        /// <summary>
        /// 
        /// </summary>
        public T Channel
        { get; set; }
    
        public CommunicationState ChannelState
        {
            get
            {
                ICommunicationObject c = (ICommunicationObject)Channel;
                return c.State;
            }
        }
    
        #region IDisposable Members
        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        public void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                    Close();
    
                this._disposed = true;
            }
    
        }
    
        public void Close()
        {
            ICommunicationObject c = Channel as ICommunicationObject;
    
            if (c.State == CommunicationState.Faulted)
                c.Abort();
    
            c.Close();
    
        }
    
        #endregion
    }
    

    然后基本上你在某处创建一个静态 ChannelFactory(我想这将被传递给你的小外观),然后调用 RemotingClient。像这样:

    public class MinorFacade1
    {
        private static ChannelFactory<IMyServiceContract> MyFactory{ get; set; }
    
        public MinorFacade1(ChannelFactory<IMyServiceContract> factory)
        {
            MyFactory = factory;
         }
    
    
        public void DoSomeAwesomeWcfCall()
        {
           using(RemotingClient<IMyServiceContract> proxy = new RemotingClient<IMyServiceContract>(MyFactory)
                proxy.Channel.ThisIsAnAwesomeWcfCall();
         }
    

    }

    【讨论】:

      猜你喜欢
      • 2013-03-06
      • 2010-12-06
      • 1970-01-01
      • 2014-01-18
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多