public PluginHandlerOnReceiveResult OnReceive(PluginMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } _messageQueue.Enqueue(message); if (message.MessageName == RegisterPluginMessageName) { return PluginHandlerOnReceiveResult.RefreshDependencies; } return PluginHandlerOnReceiveResult.Default; }
private void OnError(PluginMessage requestMessage, string errorMessage) { SendMessage( requestMessage.PluginId, message: new PluginResponseMessage { MessageId = requestMessage.MessageId, MessageName = requestMessage.MessageName, Error = errorMessage, }); }
private void OnNoop(PluginMessage requestMessage, string errorMessage) { // We only want to send a no-op message if there's an associated message id on the request message. if (requestMessage.MessageId != null) { SendMessage( requestMessage.PluginId, message: new NoopPluginResponseMessage { MessageId = requestMessage.MessageId, MessageName = requestMessage.MessageName, Error = errorMessage }); } }
private PluginResponseMessage RegisterPlugin( PluginMessage message, IAssemblyLoadContext assemblyLoadContext) { var registerData = message.Data.ToObject<PluginRegisterData>(); var response = new RegisterPluginResponseMessage { MessageName = RegisterPluginMessageName }; var pluginId = message.PluginId; var registerDataTypeCacheKey = registerData.GetFullTypeCacheKey(); IPlugin plugin; Type pluginType; if (!_pluginTypeCache.TryGetValue(registerDataTypeCacheKey, out pluginType)) { try { Assembly assembly; if (!_assemblyCache.TryGetValue(registerData.AssemblyName, out assembly)) { assembly = assemblyLoadContext.Load(registerData.AssemblyName); } pluginType = assembly.GetType(registerData.TypeName); } catch (Exception exception) { response.Error = exception.Message; return response; } } if (pluginType == null) { response.Error = Resources.FormatPlugin_TypeCouldNotBeLocatedInAssembly( pluginId, registerData.TypeName, registerData.AssemblyName); return response; } else { // We build out a custom plugin service provider to add a PluginMessageBroker and // IAssemblyLoadContext to the potential services that can be used to construct an IPlugin. var pluginServiceProvider = new PluginServiceProvider( _hostServices, messageBroker: new PluginMessageBroker(pluginId, _sendMessageMethod)); plugin = ActivatorUtilities.CreateInstance(pluginServiceProvider, pluginType) as IPlugin; if (plugin == null) { response.Error = Resources.FormatPlugin_CannotProcessMessageInvalidPluginType( pluginId, pluginType.FullName, typeof(IPlugin).FullName); return response; } } Debug.Assert(plugin != null); int resolvedProtocol; if (!registerData.Protocol.HasValue) { // Protocol wasn't provided, use the plugin's protocol. resolvedProtocol = plugin.Protocol; } else { // Client and plugin protocols are max values; meaning support is <= value. The goal in this method is // to return the maximum protocol supported by both parties (client and plugin). resolvedProtocol = Math.Min(registerData.Protocol.Value, plugin.Protocol); // Update the plugins protocol to be the resolved protocol. plugin.Protocol = resolvedProtocol; } _registeredPlugins[pluginId] = plugin; response.Protocol = resolvedProtocol; return response; }
private void PluginMessage(PluginMessage message, IAssemblyLoadContext assemblyLoadContext) { IPlugin plugin; if (_registeredPlugins.TryGetValue(message.PluginId, out plugin)) { try { if (!plugin.ProcessMessage(message.Data, assemblyLoadContext)) { // Plugin didn't handle the message. Notify the client that we no-oped so it can respond // accordingly. OnNoop( message, Resources.FormatPlugin_PluginCouldNotHandleMessage(message.PluginId, message.MessageName)); } } catch (Exception exception) { OnError( message, errorMessage: Resources.FormatPlugin_EncounteredExceptionWhenProcessingPluginMessage( message.PluginId, exception.Message)); } } else { OnError( message, errorMessage: Resources.FormatPlugin_UnregisteredPluginIdCannotReceiveMessages(message.PluginId)); } }
private void UnregisterMessage(PluginMessage message) { if (!_registeredPlugins.Remove(message.PluginId)) { var faultedRegistrationIndex = _faultedRegisterPluginMessages.FindIndex( faultedMessage => faultedMessage.PluginId == message.PluginId); if (faultedRegistrationIndex == -1) { OnError( message, errorMessage: Resources.FormatPlugin_UnregisteredPluginIdCannotUnregister(message.PluginId)); return; } else { _faultedRegisterPluginMessages.RemoveAt(faultedRegistrationIndex); } } SendMessage( message.PluginId, new PluginResponseMessage { MessageName = UnregisterPluginMessageName, }); }
private void RegisterMessage(PluginMessage message, IAssemblyLoadContext assemblyLoadContext) { var response = RegisterPlugin(message, assemblyLoadContext); if (!response.Success) { _faultedRegisterPluginMessages.Add(message); } SendMessage(message.PluginId, response); }