Mijn assembly-structuur is, in de simpelste vorm, als volgt:
server: server-programma, interfaces, plugin interfaces, plugin.
client: client-programma, interfaces, plugin interfaces.
Het probleem is zowat terug te leiden tot:
Aan de client kant:
De exception die ik krijg is:
Google vertelt me dat dit niet zo vaak voorkomt, maar een goeie hint was om de Plugins assembly naast het client programma te zetten. Dit werkt, maar is natuurlijk niet netjes. De clients hebben helemaal niets te maken met de implementatie van mijn interfaces.
Remoting doet alsof ik het object wil hebben, terwijl ik enkel geinteresseerd ben in de interface natuurlijk. Het rare van de zaak is dat de plugin zelf wel werkt, terwijl het sub-object die in diezelfde assembly zit, niet werkt.
Tweede onbegrijpbare is dat de exceptie tijdens het _deserializen_ aan de _server_ kant opgeworpen wordt, terwijl ik toch echt de fout zou verwachten tijdens het deserializen aan de client kant.
server: server-programma, interfaces, plugin interfaces, plugin.
client: client-programma, interfaces, plugin interfaces.
Het probleem is zowat terug te leiden tot:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| // interfaces assembly: public interface IPluginBase { /* */ } public interface ISomePluginContainer { IPluginBase GetPlugin(); } // plugin interfaces assembly: public interface ISomeObject { /* */ } public interface ISpecificPlugin { ISomeObject GetSomeObject(); } // plugin assembly public class SomeObject : MarshalByRefObject, ISomeObject { /* */ } public class SpecificPlugin : MarshalByRefObject, IPluginBase, ISpecificPlugin { public ISomeObject GetSomeObject() { return new SomeObject(); } } // programma assembly class SomePluginContainer : MarshalByRefObject, ISomePluginContainer { // plugins worden dynamisch geladen met reflection. IPluginBase GetPlugin() { } } static int main() { // set up remoting // SomePluginContainer ctr = new SomePluginContainer(); ObjRef ref = RemotingServices.Marshal(ctr); } |
Aan de client kant:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
| // refereert zowel interfaces als plugin interfaces assembly static int main { // setup remoting ISomePluginContainer ctr = (ISomePluginContainer)Activator.GetObject(...); IPluginBase plugin = ctr.GetPlugin(); if (plugin is ISpecificPlugin) { ISpecificPlugin specPlugin = plugin as ISpecificPlugin; ISomeObject obj = specPlugin.GetSomeObject(); // hier krijg ik de fout. } } |
De exception die ik krijg is:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| System.Runtime.Serialization.SerializationException: Parserfout. Er is geen assembly gekoppeld aan XML-sleutel a2:http://schemas.microsoft.com/clr/nsassem/XXX.Plugins/XXX.Plugins%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D22271cae2e665f51 SomeObject Server stack trace: bij System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessGetType(String value, String xmlKey, String& assemblyString) bij System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessArray(ParseRecord pr, Int32 firstIndex, Boolean IsInterop) bij System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessType(ParseRecord pr, ParseRecord objectPr) bij System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessAttributes(ParseRecord pr, ParseRecord objectPr) bij System.Runtime.Serialization.Formatters.Soap.SoapHandler.StartChildren() bij System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml() bij System.Runtime.Serialization.Formatters.Soap.SoapParser.Run() bij System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize(HeaderHandler handler, ISerParser serParser) bij System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream serializationStream, HeaderHandler handler) bij System.Runtime.Remoting.Channels.CoreChannel.DeserializeSoapResponseMessage(Stream inputStream, IMessage requestMsg, Header[] h, Boolean bStrictBinding) bij System.Runtime.Remoting.Channels.SoapClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream) bij System.Runtime.Remoting.Channels.SoapClientFormatterSink.SyncProcessMessage(IMessage msg) Exception rethrown at [0]: bij System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) bij System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) bij XXX.Interfaces.Plugins.ISpecificPlugin.GetSomeObject() |
Google vertelt me dat dit niet zo vaak voorkomt, maar een goeie hint was om de Plugins assembly naast het client programma te zetten. Dit werkt, maar is natuurlijk niet netjes. De clients hebben helemaal niets te maken met de implementatie van mijn interfaces.
Remoting doet alsof ik het object wil hebben, terwijl ik enkel geinteresseerd ben in de interface natuurlijk. Het rare van de zaak is dat de plugin zelf wel werkt, terwijl het sub-object die in diezelfde assembly zit, niet werkt.
Tweede onbegrijpbare is dat de exceptie tijdens het _deserializen_ aan de _server_ kant opgeworpen wordt, terwijl ik toch echt de fout zou verwachten tijdens het deserializen aan de client kant.
ASSUME makes an ASS out of U and ME