2010-09-20 8 views
14

Mam podstawową klasę DomainObject dla wszystkich moich obiektów biznesowych, których używam z NHibernate. Zawiera właściwość Id.Jak uzyskać typ jednostki na obiekcie, który może być obiektem proxy NHibernate?

public abstract class DomainObject 
{ 
    public virtual int Id { get; private set; } 
} 

Chciałbym napisać IEqualityComparer, aby porównać moje obiekty domeny. Jeśli dwa obiekty mają ten sam obiekt Id i są tym samym rodzajem obiektu, powinny być równe. Jednak gdy używam GetType(), aby uzyskać typ obiektu, zwróci on typ proxy NHibernate. Więc ten kod:

bool IEqualityComparer.Equals(object x, object y) 
{ 
    // null checking code skipped here 
    if(x is DomainObject && y is DomainObject) 
    { 
      return ((DomainObject) x).Id == ((DomainObject) y).Id 
        && x.GetType() == y.GetType(); 
    } 
    return x.Equals(y); 
} 

nie działa poprawnie, ponieważ rodzaju x is Asset ale rodzaj y is AssetProxy21879bba3e9e47edbbdc2a546445c657.

Jak zatem uzyskać typ jednostki na obiekcie, który może być obiektem proxy NHibernate? tj. w powyższym przykładzie Asset zamiast AssetProxy21879bba3e9e47edbbdc2a546445c657?

+0

jestem 99% pewien, że jest to duplikat, ale jestem zbyt leniwy, aby go teraz szukać: -) –

+3

Proszę pokazać mi ten, który duplikuje, wyglądałem na cały stackoverflow dla niego. –

Odpowiedz

20

Można uzyskać prawdziwy typ serwera proxy z:

NHibernateUtil.GetClass(x); 

lub można dodać metodę DomainObject jak:

public virtual Type GetTypeUnproxied() 
{ 
    return GetType(); 
} 

który jest naprawdę śliska i nie zależy bezpośrednio od NHibernate.

Alternatywnie, można podejść do problemu, mówiąc, trzeba uzyskać prawdziwy obiekt, zamiast pełnomocnika, który, jeśli sesja jest poręczny, można zrobić z:

session.PersistenceContext.Unproxy(x); 

Jak wspomniano w innym odpowiedź, jeśli próbujesz wprowadzić równe wartości, dobrym pomysłem byłoby sprawdzenie Sharp architecture implementation of Equals.

+1

Zauważ, że jeśli używasz Castle Windsor, GetClass może zwrócić typ Proxy.Zobacz ten wątek w inny sposób, aby go rozwiązać: http://stackoverflow.com/a/1420816/348841 –

2

Aby uzyskać rzeczywisty obiekt zamiast pełnomocnictwa można użyć

session.PersistenceContext.Unproxy(proxyObject) 

Ale myślę, że należy spojrzeć na Sharp architecture implementation na równi.

+0

Należy zauważyć, że prawdopodobnie bardziej interesuje go metoda GetTypeUnproxied() pod adresem http://github.com/codai/Sharp-Architecture/blob/master/src/SharpArch/SharpArch.Core/DomainModel/BaseObject.cs - ale +1 dla dobrego odniesienia impl. – DanP

+0

W tym przypadku nie mam dostępu do sesji w tym kodzie. Dzięki za odniesienie do Equals w architekturze Sharp, nie dotyczy to mnie, ponieważ piszę test równy dla testów, więc nie musi on obsługiwać wszystkich przypadków, ale nadal był dobrym referencją. I dziękuję Danowi za link do kodu GetTypeUnproxied(), który jest bardziej tym, co mnie interesuje. –

0

Możesz zaimplementować właściwość backdoora zgodnie z opisem here, aby uzyskać rzeczywistą instancję nieprostowatą.

-1

Wziąłem inny aproach w projekcie produkcji. Po prostu mają globalny HiLow id-generator, który generuje unikalne identyfikatory dla wszystkich typów to mogę:

// in DomainEntity 
public override bool Equals(object obj) 
{ 
    var other = obj as DomainEntity; 
    if (Id == 0) // IsTransient() 
     return ReferenceEquals(this, other); 
    else 
     return (other != null) && (Id == other.Id); 
} 

// Comparer 
bool IEqualityComparer.Equals(object x, object y) 
{ 
    return object.Equals(x, y); 
} 
Powiązane problemy