2014-07-08 61 views
0

這是我的情況,我寫了一個wcf,它和果園完美地合作。 我要去,所以我加ServiceAdapter 和ClientServiceLocator到我的項目來處理事件的消息,如警告和例外:在果園裏處理WCF服務和與果園通知結合

ServiceAdapter:

public class ServiceAdapter<TService> 
where TService : class, IContract 
{ 
    public TResult Execute<TResult>(Func<TService, TResult> command) 
     where TResult : IDtoResponseEnvelop 
    { 
     try 
     { 
      var dispatcher = ClientServiceLocator.Instance().CommandDispatcher; 
      var result = DispatchCommand(() => dispatcher.ExecuteCommand(command)); 
      if (result.Response.HasWarning) 
      { 
       ClientServiceLocator.Instance() 
        .WarningManager 
        .HandleBusinessWarning(result.Response.BusinessWarnings); 

      } 
      if (result.Response.HasException) 
      { 
       ClientServiceLocator.Instance() 
        .ExceptionManager 
        .HandleBusinessException(result.Response.BusinessException); 
      } 
      return result; 
     } 
     finally 
     { 
     } 
    } 

    private static TResult DispatchCommand<TResult>(Func<TResult> dispatcherCommand) 
     where TResult : IDtoResponseEnvelop 
    { 
     var asynchResult = dispatcherCommand.BeginInvoke(null, null); 
     while (!asynchResult.IsCompleted) 
     { 
     } 
     return dispatcherCommand.EndInvoke(asynchResult); 
    } 
} 

ClientServiceLocator:

public class ClientServiceLocator 
{ 
    static readonly Object LocatorLock = new object(); 
    private static ClientServiceLocator InternalInstance; 

    private ClientServiceLocator() { } 

    public static ClientServiceLocator Instance() 
    { 
     if (InternalInstance == null) 
     { 
      lock (LocatorLock) 
      { 
       // in case of a race scenario ... check again 
       if (InternalInstance == null) 
       { 
        InternalInstance = new ClientServiceLocator(); 
       } 
      } 
     } 
     return InternalInstance; 
    } 

    #region IClientServices Members 

    public IBusinessExceptionManager ExceptionManager { get; set; } 
    public IBusinessWarningManager WarningManager { get; set; } 
    public ICommandDispatcher CommandDispatcher { get; set; } 

    #endregion 

} 

BusinessExceptionManager:

class BusinessExceptionManager 
    : IBusinessExceptionManager, IDependency 
{ 
    private Localizer T { get; set; } 
    private readonly INotifier _notifier; 
    public BusinessExceptionManager(INotifier notifier) 
    { 
     _notifier = notifier; 
     T = NullLocalizer.Instance; 
    } 
    public void HandleBusinessException(BusinessExceptionDto exceptionDto) 
    { 
     _notifier.Add(NotifyType.Error, T(exceptionDto.Message)); 
    } 
} 

BusinessWarningManager:

class BusinessWarningManager 
    : IBusinessWarningManager, IDependency 
{ 
    private Localizer T { get; set; } 
    private readonly INotifier _notifier; 

    public BusinessWarningManager(INotifier notifier) 
    { 
     _notifier = notifier; 
     T = NullLocalizer.Instance; 
    } 
    public void HandleBusinessWarning(IEnumerable<BusinessWarning> warnings) 
    { 
     var message = string.Join(Environment.NewLine, warnings.Select(w => w.Message)); 
     _notifier.Add(NotifyType.Warning, T(message)); 
    } 
} 

這裏是控制器:

public class SectorsAdminController : Controller 
{ 
    private dynamic Shape { get; set; } 
    private Localizer T { get; set; } 
    private readonly INotifier _notifier; 
    private readonly ISiteService _siteService; 
    private ServiceAdapter<ISectorService> _sectorServiceAdapter; 

    public SectorsAdminController(ISiteService siteService, INotifier notifier, IShapeFactory shapeFactory) 
    { 
     Shape = shapeFactory; 
     T = NullLocalizer.Instance; 
     _notifier = notifier; 
     _siteService = siteService; 
     _sectorServiceAdapter = new ServiceAdapter<ISectorService>(); 
    } 

    public ActionResult Index() 
    { 
     var model = Shape.Sectors(Sectors: _sectorServiceAdapter.Execute(s => s.FindAll()).Sectors); 
     return View((object)model); 
    } 
} 

以下是錯誤:

糟糕。出錯了...抱歉

發生未處理的異常並且請求被終止。請刷新頁面。如果錯誤仍然存​​在,請返回

未將對象引用設置爲對象的實例。

System.NullReferenceException:未將對象引用設置爲對象的實例。服務器堆棧跟蹤:at SAS.Admin.Services.ServiceAdapter 1.<>c__DisplayClass3 1.b__0()at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md,Object [] args,Object server,Object [] & outArgs)at System .Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg,IMessageSink replySink)在System.Runtime.Remoting的System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(消息reqMsg,布爾bProxyCase)的[0]處重新執行異常。 Proxies.RemotingProxy.Invoke(Object NotUsed,MessageData & msgData)at System.Func 1.EndInvoke(IAsyncResult result) at SAS.Admin.Services.ServiceAdapter 1.在System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor,IDictionary 012)執行[TResult](函數2 command) at SAS.Admin.Controllers.SectorsAdminController.Index() at lambda_method(Closure , ControllerBase , Object[]) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary)2 .CallEndDelegate(IAsyncResult asyncResult)在System.Web.Mvc.Async.AsyncControllerActionInvo ker.AsyncInvocationWithFilters.b__3f()在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters。 <> c__DisplayClass48.b__41()在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters。 <> c__DisplayClass48.b__41()

回答

0

爲什麼要使用Poor's Man Singleton?我會從IClientServices成員開始使用ISingletonDependency,如果這是您需要的
擺脫可怕的ServiceLocator,然後將IDependency添加到您的ServiceAdapter。

事實上,改變一切讓Orchard處理實例。
我不明白爲什麼您的ServiceAdapter不能成爲您的Controller實例化的簡單服務,那麼您的IClientServices中的每一個都會在您的服務中創建爲Providers。