Пример #1
0
        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;
        }
Пример #2
0
 private void OnError(PluginMessage requestMessage, string errorMessage)
 {
     SendMessage(
         requestMessage.PluginId,
         message: new PluginResponseMessage
         {
             MessageId = requestMessage.MessageId,
             MessageName = requestMessage.MessageName,
             Error = errorMessage,
         });
 }
Пример #3
0
 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
             });
     }
 }
Пример #4
0
        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;
        }
Пример #5
0
 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));
     }
 }
Пример #6
0
        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,
                });
        }
Пример #7
0
        private void RegisterMessage(PluginMessage message, IAssemblyLoadContext assemblyLoadContext)
        {
            var response = RegisterPlugin(message, assemblyLoadContext);

            if (!response.Success)
            {
                _faultedRegisterPluginMessages.Add(message);
            }

            SendMessage(message.PluginId, response);
        }