IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

AppDomain + MarshalByRefObject = 'Unable to cast transparent proxy to type'


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 64
    Points : 39
    Points
    39
    Par défaut AppDomain + MarshalByRefObject = 'Unable to cast transparent proxy to type'
    Bonsoir,
    J'ai trouvé pas mal de post sur le même sujet mais je n'ai pas trouvé la solution à mon pb.

    J'ai une classe de base qui hérite de MarshalByRefObject et implémente une interface:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    [Serializable]
        public abstract class CarrierLabelBase : MarshalByRefObject, ICarrierLabel
    J'ai une autre assembly contenant une classe Carrier qui hérite de CarrierLabelBase.
    Je souhaite utiliser cette classe de l'assembly dans un domaine d'application. Je crée mon AppDomain et voici la suite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ICarrierLabel carrierLabel =(ICarrierLabel) _myDomain.CreateInstanceAndUnwrap(assemblyName, carrierName + "CarrierLabel");
    Si j’exécute celà depuis VS2005, pas de soucis. Il trouve ma DLL et le cast se passe bien.

    Mais le programme est en fait utilisé par MsAccess et au moment de faire le cast, j'ai l'erreur suivante:
    Unable to cast transparent proxy to type" car en effet, le type est devenu "System.MarshalByRefObject".
    J'ai tout retourné dans tous les sens et là, je bloque.
    Pouvez vous me filer un coup de main?
    Cdlt.

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 64
    Points : 39
    Points
    39
    Par défaut
    Bonjour,
    Je n'ai malheureusement toujours pas trouvé la solution à mon problème.
    Mais même en .net (sans appel depuis MsAccess), les performances sont très dégradées en passant par un appDomain personalisé. j'ai des contraintes de temps de traitement.
    Pour l'instant, j'ai mis de côté cette modification mais si qq'un peut quand même me trouver une solution au problème initial...
    Merci.

  3. #3
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut cast sur interface au lieu de classe qualifie
    bonjour cyril

    ton probleme vient du cast sur l'interface au lieu de la classe Carrier.
    L'interface faut-il le rappeler sert à controler si les types sont corrects mais pas à faire des appels sur elle(sauf quand tu es en environnement com ou il existe d'ailleurs specialement une fonction CreateInstanceFromCom).
    bref voici un exemple sur excel ou j'ai mis un projet :
    1/CetAssembly :
    -squelette de ton interface ICarrierLabel et de la classe ancetre CarrierLabelBase
    2/AutreAssembly:
    -squelette de la classe Carrier herite de CarrierLabelBase
    3/winform:
    -qui charge l'assembly AutreAssembly ,instancie Carrier et appelle Excel (interop) pour acceder aux membres de Carrier.
    -N B: AppDomain exige la presence dans dossier bin (ou release suivant le cas ) de l'assembly AutreAssembly.dll qui contient la classe Carrier mais,mais....de tous les assemblys dependant c.à.d egalement de l'assembly CetAssembly.dll dans le dossier bin.

    code sous vs 2008:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
     
    'projet CetAssembly
    Public Interface ICarrierLabel
        Sub PP(ByVal dd As Double)
        Function NN(ByVal aa As String) As String
    End Interface
    <Serializable()> _
    Public MustInherit Class CarrierLabelBase
        Inherits MarshalByRefObject
        Implements ICarrierLabel
        Public dd1 As Double
        Public nom As String
        Public Sub New()
            Me.dd1 = 0.0
            Me.nom = "Bonjour CetAssembly"
        End Sub
     
        Public Function NN(ByVal aa As String) As String Implements ICarrierLabel.NN
            Return aa
        End Function
     
        Public Sub PP(ByVal dd As Double) Implements ICarrierLabel.PP
            dd1 = dd * 100.0
        End Sub
    End Class
    'projet AutreAssembly
    Imports CetAssembly
    Public Class Carrier
        Inherits CarrierLabelBase
        Public str As String
        Public Sub New()
            Me.str = "bonjour ici Autre Assembly"
        End Sub
    End Class
     
    'projet WinForm principal
    '-----------------------------------------------------------------------
    'AutreAssembly  => l'assembly qui definit la classe Carrier
    '-----------------------------------------------------------------------
    'NB:Access à l'objet classe Carrier se fait "via" 
    'un "cast" sur la classe et non l'interface.
    '-----------------------------------------------------------------------
    'Bouton btnTestNvAppDomain pour tester creation d'un nouveau AppDomain
    'Bouton btnCreeCarriere pour creer un nouveau AppDomain et acceder à classe Carrier
    'Bouton btnTestNvAppDomain creer un nouveau AppDomain et acceder à classe Carrier dans Excel
     
    Imports System
    Imports System.AppDomain
    Imports System.IO
    Imports System.Threading
    'namespace  Reflection necessaire
    Imports System.Reflection
    'namespace  Runtime.Remoting necessaire
    Imports System.Runtime.Remoting
    Imports OXL = Microsoft.Office.Interop.Excel
    Public Class frmLoadAssembAppDomain
        Dim nouvDomain As AppDomain
        Dim nomAppDomain As String
        Dim dossier As String
        Public Sub New()
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
     
        End Sub
        'Cree un nouveau AppDomain
        Private Sub btnTestNvAppDomain_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTestNvAppDomain.Click
     
            'Affiche le nom du AppDomain courant
            '----------------------------------------------------
            nomAppDomain = Thread.GetDomain().FriendlyName
            TextBox1.Text = "appDomain courant :" & nomAppDomain & vbCrLf
     
            ' Initialise un objet  AppDomainSetup .
            '----------------------------------------------------
            dossier = System.Environment.CurrentDirectory
            Dim setupInfo As New AppDomainSetup
            ' Configure application domain setup information.
            setupInfo.ApplicationBase = dossier
            setupInfo.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
            setupInfo.PrivateBinPath = "bin;"
            setupInfo.DisallowCodeDownload = True
            ' Cree un nouveau domain d'application domain (argument evidence= Nothing)
            ' Enregistrer une reference de ce nouvau AppDomain pour pouvoir
            ' etre retrouver plus tard.
            '----------------------------------------------------
            nouvDomain = AppDomain.CreateDomain("NouveauAppDomain", _
             Nothing, setupInfo)
     
            'Affiche nom Nouveau AppDomain.
            '----------------------------------------------------
            nomAppDomain = nouvDomain.FriendlyName
            TextBox1.Text = TextBox1.Text & "Main method complete..." & nomAppDomain & vbCrLf
     
            ' Decharge le nouveau AppDomain. ceci detruit ses objets et invalide 
            ' l'objet proxy .
            '----------------------------------------------------
            AppDomain.Unload(nouvDomain)
        End Sub
        'Cree un Nouveau AppDomain et charge AutreAssembly
        'pour acceder à la classe Carrier
        Private Sub btnCreeCarriere_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreeCarriere.Click
            'Affiche le nom du AppDomain courant
            '----------------------------------------------------
            nomAppDomain = Thread.GetDomain().FriendlyName
            TextBox1.Text = "appDomain courant :" & nomAppDomain & vbCrLf
     
            'Initialise un objet  AppDomainSetup
            '----------------------------------------------------
            dossier = System.Environment.CurrentDirectory
            Dim setupInfo As New AppDomainSetup
            ' Configure application domain setup information.
            setupInfo.ApplicationBase = dossier
            setupInfo.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
            setupInfo.PrivateBinPath = "bin;"
            setupInfo.DisallowCodeDownload = True
            ' Cree un nouveau domain d'application domain (argument evidence= Nothing)
            ' Enregistrer une reference de ce nouvau AppDomain pour pouvoir
            ' etre retrouver plus tard.
            '----------------------------------------------------
            nouvDomain = AppDomain.CreateDomain("NouveauAppDomain", _
             Nothing, setupInfo)
            'Affiche nom Nouveau AppDomain.
            nomAppDomain = nouvDomain.FriendlyName
            TextBox1.Text = TextBox1.Text & "Main method complete..." & nomAppDomain & vbCrLf
     
            'CHARGE ASSEMBLY EXTERNE & CREATION DE L'OBJET Carrier
            '----------------------------------------------------
            dossier = System.Environment.CurrentDirectory
            Dim nomNamespace As String = "AutreAssembly."
            Dim nomClasseQualifie = nomNamespace & "Carrier"
            Dim nomAssembly As String = "AutreAssembly.dll"
            'CHARGE ASSEMBLY EXTERNE  Carrier
            '----------------------------------------------------
            Dim objAssemb As Assembly = Assembly.LoadFrom(nomAssembly)
     
            'CREE UN OBJET DE TYPE  Carrier
            '----------------------------------------------------
            Dim carrierLabel As Object = objAssemb.CreateInstance(nomClasseQualifie)
            ' Init une instance  MBR de Carrier dans nouveau domain d'application.
            ' Un handle proxy vers l'object est retourne.
            '----------------------------------------------------
            'Unwrap du Handle vers le type Carrier
            carrierLabel = _
                    nouvDomain.CreateInstanceFromAndUnwrap(nomAssembly, _
                   nomClasseQualifie)
     
            btnCreeCarriere.Enabled = False
            'Appel d'une sub,function et var membre de l'object via le proxy
            '----------------------------------------------------
            carrierLabel.PP(125.0)
            TextBox2.Text = carrierLabel.NN(" mbr Carrier initialisee.dans :" & nomAppDomain) & vbCrLf
            TextBox2.Text = TextBox2.Text & carrierLabel.str & vbCrLf
            TextBox2.Text = TextBox2.Text & carrierLabel.dd1.ToString & vbCrLf
            TextBox2.Text = TextBox2.Text & carrierLabel.nom & vbCrLf
            ' Decharge le nouveau AppDomain. ceci detruit ses objets et invalide 
            ' l'objet proxy .
            '----------------------------------------------------
            AppDomain.Unload(nouvDomain)
            Try
                'Appel de nouveau la fonction NN .
                'Echec car le nouveau AppDomain a ete decharge.
                TextBox2.Text = TextBox2.Text & carrierLabel.NN(" mbr Carrier initialisee.dans :" & nomAppDomain)
            Catch ex As AppDomainUnloadedException
                TextBox2.Text = TextBox2.Text & "Echec Appel.Ceci est previsible." & ex.Message
            End Try
        End Sub
        'Cree un Nouveau AppDomain et charge AutreAssembly
        '& accede à la classe Carrier à partir d' Excel
        Private Sub btnExcelCOM_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExcelCOM.Click
            'Affiche le nom du AppDomain courant
            '----------------------------------------------------
            nomAppDomain = Thread.GetDomain().FriendlyName
            TextBox3.Text = "appDomain courant :" & nomAppDomain & vbCrLf
     
            'Initialise un objet  AppDomainSetup
            '----------------------------------------------------
            dossier = System.Environment.CurrentDirectory
            Dim setupInfo As New AppDomainSetup
            ' Configure application domain setup information.
            setupInfo.ApplicationBase = dossier
            setupInfo.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
            setupInfo.PrivateBinPath = "bin;"
            setupInfo.DisallowCodeDownload = True
            ' Cree un nouveau domain d'application domain (argument evidence= Nothing)
            ' Enregistrer une reference de ce nouvau AppDomain pour pouvoir
            ' etre retrouver plus tard.
            '----------------------------------------------------
            nouvDomain = AppDomain.CreateDomain("NouveauAppDomain", _
             Nothing, setupInfo)
            'Affiche nom Nouveau AppDomain.
            nomAppDomain = nouvDomain.FriendlyName
            TextBox3.Text = TextBox3.Text & "Main method complete..." & nomAppDomain & vbCrLf
     
            'CHARGE ASSEMBLY EXTERNE & CREATION DE L'OBJET Carrier
            '----------------------------------------------------
            Dim nomNamespace As String = "AutreAssembly."
            Dim nomClasseQualifie = nomNamespace & "Carrier"
            Dim nomAssembly As String = "AutreAssembly.dll"
     
            'CHARGE ASSEMBLY EXTERNE  Carrier
            '----------------------------------------------------
            Dim objAssemb As Assembly = Assembly.LoadFrom(nomAssembly)
            'CREE UN OBJET DE TYPE  Carrier
            '----------------------------------------------------
            Dim carrierLabel As Object = objAssemb.CreateInstance(nomClasseQualifie)
            ' Init une instance  MBR de Carrier dans nouveau domain d'application.
            ' Un handle proxy vers l'object est retourne.
            '----------------------------------------------------
            'Unwrap du Handle vers le type Carrier
            carrierLabel = _
                    nouvDomain.CreateInstanceFromAndUnwrap(nomAssembly, _
                   nomClasseQualifie)
     
            btnTestNvAppDomain.Enabled = False
            btnCreeCarriere.Enabled = False
            'Appel d'une sub,function et var membre de l'object via le proxy
            carrierLabel.PP(125.0)
            TextBox3.Text = TextBox3.Text & carrierLabel.NN(" mbr Carrier initialisee.dans :" & nomAppDomain) & vbCrLf
            TextBox3.Text = TextBox3.Text & carrierLabel.str & vbCrLf
            TextBox3.Text = TextBox3.Text & carrierLabel.dd1 & vbCrLf
            TextBox2.Text = TextBox2.Text & carrierLabel.nom & vbCrLf
            '----------------------Accede à l'Objet Carriere l'objet à Com EXCEL -------------------------
            '----------------------------------------------------
            Dim objAppExcel As OXL.Application = New OXL.Application
            Dim objWorkbook As OXL.Workbook = objAppExcel.Workbooks.Add()
            Dim objSheet As OXL.Worksheet = objWorkbook.Worksheets(1)
            Dim objRange As OXL.Range = Nothing
            objRange = objSheet.Cells(1, 1)
            objRange.Value = carrierLabel.NN(" mbr Carrier initialisee.dans :" & nomAppDomain) & vbCrLf
            objRange = objSheet.Cells(1, 2)
            objRange.Value = carrierLabel.str
            objRange = objSheet.Cells(1, 3)
            objRange.Value = carrierLabel.dd1
            objRange = objSheet.Cells(1, 4)
            objRange.Value = carrierLabel.nom
            objAppExcel.Visible = True
            ' Decharge le nouveau AppDomain. ceci detruit ses objets et invalide 
            ' l'objet proxy .
            '----------------------------------------------------
            AppDomain.Unload(nouvDomain)
            btnTestNvAppDomain.Enabled = True
            btnCreeCarriere.Enabled = True
        End Sub
     
     
    End Class
    bon code....

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 64
    Points : 39
    Points
    39
    Par défaut
    Merci.
    J'essaies de mettre en place tout ça dès que j'ai un peu de temps et je vous fais un retour.
    Bonne journée.

Discussions similaires

  1. List et String cast entre les deux types
    Par sas1986 dans le forum Langage
    Réponses: 3
    Dernier message: 08/07/2011, 10h32
  2. Unable to cast object of type "System.Windows.Application"
    Par OminiuS dans le forum Silverlight
    Réponses: 11
    Dernier message: 15/09/2010, 16h28
  3. Unable to Cast - besoin d'un éclaircissement
    Par maVariable dans le forum Windows Forms
    Réponses: 1
    Dernier message: 12/05/2009, 11h12
  4. Réponses: 11
    Dernier message: 06/05/2009, 17h13
  5. cast explicite requis pour type void **
    Par ram-0000 dans le forum C++
    Réponses: 2
    Dernier message: 30/04/2008, 17h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo