2012-07-13 35 views
6

Używam LINQPad do testowania kodu (co za wspaniały produkt, muszę powiedzieć), ale teraz napotykam wyjątek, gdy próbuję ustawić Thread.CurrentPrincipal w niestandardowej IPrincipal, która jest zaznaczona z SerializableAttribute następujące próbki że zademonstrować problemlinqpad i niestandardowe serializable IPrincipal

void Main() 
{ 
    Thread.CurrentPrincipal = new MyCustomPrincipal(); 
} 

// Define other methods and classes here 
[Serializable] 
public class MyCustomPrincipal : IPrincipal 
{ 
    public bool IsInRole(string role) 
    { 
     return true; 
    } 

    public IIdentity Identity 
    { 
     get 
     { 
      return new WindowsIdentity("RECUPERA\\m.casamento"); 
     } 
    } 
} 

Kiedy uruchomić ten kod w LINQPad (C# program jako języka) pojawia się następujący wyjątek

Type is not resolved for member 'UserQuery+MyCustomPrincipal,query_nhxfev, Version=0.0.0.0, 
Culture=neutral, PublicKeyToken=null' 
RuntimeMethodInfo: PluginWindowManager.get_Form() 

jeśli usunąć Serializable atrybutu wszystko idzie dobrze. Wydaje się, że jest to problem związany z architekturą AppDomain używaną przez LINQPad i niemożnością znalezienia zespołu definiującego MyCustomPrincipal. Sądzę również, że zdefiniowanie MyCustomPrincipal w innym zestawie i umieszczenie go w GAC rozwiąże problem, ale nie jest to opcja dla mnie. Ktoś ma pomysł?

Dzięki Marco

EDIT: Nie wiem, czy to może pomóc, ale miałem ten sam problem z SqlDependency.Start: putting Serializable na IPrincipal sprawiło ramy rzucać błąd narzekając, że nie może znaleźć zespołu, który definiuje typ IPrincipala. I został rozwiązany z haniebną Hack:

System.Security.Principal.IPrincipal principal; 
principal = System.Threading.Thread.CurrentPrincipal; 

System.Threading.Thread.CurrentPrincipal = null; 
try 
{ 
    SqlDependency.Start(connectionString); 
     m_SqlDependencyStarted = true; 
} 
catch (Exception ex) 
{ 
    throw (ex); 
} 
finally 
{ 
    System.Threading.Thread.CurrentPrincipal = principal; 
} 
+5

To wygląda jak LINQPad kwestii. Przyjrzę się temu bardziej szczegółowo i odeślę z powrotem. –

+0

@JoeAlbahari czy masz jakieś informacje na ten temat? To naprawdę denerwujące i nie znalazłem żadnego rozwiązania. – mCasamento

+0

Pomyślałem, że znalazłem odpowiedź tutaj: http://stackoverflow.com/questions/11489673/preventing-thread-currentprincipal-propagating-across-application-domains, ale nie działa dla LINQPad, ponieważ wywołania między domenami są inicjowane z obu stron. A * dużo * comms trwa w LINQPad pomiędzy domenami hosta i pracownika - jest więcej niż tuzin metod - więc nie jest to tylko kwestia hakowania wokół jednego połączenia. –

Odpowiedz

0

Jedną sztuczką, której można użyć, jest silna nazwa zespołu zawierającego niestandardową wartość główną i umieszczenie jej w pamięci podręcznej zespołu globalnego. W ten sposób każda aplikacja znajdzie odpowiedni zestaw, ale nie jest to idealne rozwiązanie, ponieważ będziesz musiał później je usunąć. W każdym razie, aby zainstalować w GAC jeśli masz zainstalowane Visual Studio uruchomić wiersz polecenia VS i uruchomić następujące:

gacutil -i nameofassembly.dll

+0

Dzięki za odpowiedź, już wypróbowałem i działa. Uważam to bardziej za obejście, niż za rzeczywiste rozwiązanie, ale lepsze to niż nic. Zaznaczam to jednak jako odpowiedź. – mCasamento

0

Stab w ciemności, ale może to być rzeczą podpisanie z powodu zespołów przejściach?

+0

może, ale jak mogę podpisać zespół, który istnieje tylko w pamięci? Powinno to być zrobione wewnątrz LINQPad, nieprawdaż? – mCasamento

0

To wydaje się być problemem serializacji w LinqPad. Widzę, że Joseph Albahari, twórca Linqpad, potwierdził to w swoich komentarzach.

Podsumowując: do tego potrzebujemy poprawki w LinqPadzie. Nie znam żadnej pracy.