public void ProcessMessages_UnregisterPlugin_RemovesFaultedPlugins() { var pluginType = typeof(MessageBrokerCreationTestPlugin); var typeNameLookups = new Dictionary <string, Type> { { pluginType.FullName, pluginType } }; var testAssembly = new TestAssembly(typeNameLookups); var assemblyLookups = new Dictionary <string, Assembly> { { "CustomAssembly", testAssembly } }; var assemblyLoadContext = new FailureAssemblyLoadContext(assemblyLookups); var creationChecker = new PluginTypeCreationChecker(); var serviceLookups = new Dictionary <Type, object> { { typeof(PluginTypeCreationChecker), creationChecker } }; var serviceProvider = new TestServiceProvider(serviceLookups); object rawMessageBrokerData = null; var pluginHandler = new PluginHandler(serviceProvider, (data) => rawMessageBrokerData = data); var registerPluginMessage = new PluginMessage { Data = new JObject { { "AssemblyName", "CustomAssembly" }, { "TypeName", typeof(MessageBrokerCreationTestPlugin).FullName }, }, MessageName = "RegisterPlugin", PluginId = RandomGuidId }; var unregisterPluginMessage = new PluginMessage { MessageName = "UnregisterPlugin", PluginId = RandomGuidId }; pluginHandler.OnReceive(registerPluginMessage); pluginHandler.ProcessMessages(assemblyLoadContext); var messageBrokerData = Assert.IsType <PluginMessageBroker.PluginMessageWrapperData>(rawMessageBrokerData); Assert.Equal(RandomGuidId, messageBrokerData.PluginId); PluginResponseMessage responseMessage = Assert.IsType <RegisterPluginResponseMessage>(messageBrokerData.Data); Assert.False(responseMessage.Success); Assert.Equal("RegisterPlugin", responseMessage.MessageName, StringComparer.Ordinal); Assert.NotEmpty(responseMessage.Error); Assert.False(creationChecker.Created); pluginHandler.OnReceive(unregisterPluginMessage); pluginHandler.ProcessMessages(assemblyLoadContext); messageBrokerData = Assert.IsType <PluginMessageBroker.PluginMessageWrapperData>(rawMessageBrokerData); Assert.Equal(RandomGuidId, messageBrokerData.PluginId); responseMessage = Assert.IsType <PluginResponseMessage>(messageBrokerData.Data); Assert.True(responseMessage.Success); Assert.Equal("UnregisterPlugin", responseMessage.MessageName, StringComparer.Ordinal); Assert.Null(responseMessage.Error); Assert.False(creationChecker.Created); }
private void SendMessage(string pluginId, PluginResponseMessage message) { var messageBroker = new PluginMessageBroker(pluginId, _sendMessageMethod); messageBroker.SendMessage(message); }
private PluginResponseMessage RegisterPlugin( PluginMessage message, IAssemblyLoadContext assemblyLoadContext) { var registerData = message.Data.ToObject <PluginRegisterData>(); var response = new PluginResponseMessage { 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); _registeredPlugins[pluginId] = plugin; response.Success = true; return(response); }