[C#/NHibernate] Probleem bij aanmaken van entities

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bij een website waar ik op het moment mee bezig ben probeer ik ervoor te zorgen dat in mijn interface laag geen data veranderd kan worden in de entities, waardes ophalen moet natuurlijk wel kunnen, dus als we b.v. een entity user hebben dan:

Mag dit wel

Response.Write(user.Name); // Get

Mag dit niet

User.Name = “Piet”; // Set

Om dit voor elkaar te krijgen dacht ik aan het gebruiken van interfaces, de interface is public en de daadwerkelijke entity blijft private. In de interfaces zet ik dan alleen getters en in de entity zelf voeg ik de setters toe. Op deze manier moet de entity naar de domain laag gestuurd worden om hem te kunnen updaten.

Het leek te werken totdat ik het ging gebruiken met NHibernate, die zegt namelijk bij elke “many to one” relatie dat hij geen toegang heeft tot het type waar naar verwezen wordt in de relatie.

code:
1
2
3
4
Access is denied: 'Domain.Test.Theme'. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.TypeLoadException: Access is denied: 'Domain.Test.Theme'.


Dit is mijn code:

De interfaces
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace Domain.Test
{
    public interface IUser
    {
        int Id { get; }
        string Name { get; }
        ITheme Theme { get; }
    }

    public interface ITheme
    {
        int Id { get; }
        string Name { get; }
    }
}


Zoals je kan zien zijn in de interfaces geen setters te vinden, Theme in IUser is de relatie waarop het fout gaat.

De interface implementaties
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
37
38
39
40
41
42
43
44
45
namespace Domain.Test
{
    class User : IUser
    {
        private int id;
        private string name;
        private ITheme theme;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public ITheme Theme
        {
            get { return theme; }
            set { theme = value; }
        }
    }

    class Theme : ITheme
    {
        private int id;
        private string name;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}


Zoals je kan zien worden hier pas de setters toegvoegd.

Service class
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
using NHibernate;

namespace Domain.Test
{
    public static class Service
    {
        public static IUser GetById(int userId)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            return session.Get<User>(userId);
        }
    }
}


Hier gaat het fout op regel 10.
De mapping files zijn goed daar ben ik 100% zeker van, als ik de entity Theme (niet de interface) public maak in plaats van internal werkt het zonder problemen alleen dan kan ik die class benaderen vanuit me interface.

Weet iemand een andere manier om dit voor elkaar te krijgen of nog beter hoe ik dit kan laten werken met nhibernate?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Kan dit te maken hebben met de lazy loading die NHibernate toepast (vanaf een bepaalde versie dacht ik, is dit default gedrag).
Als NHibernate lazy loading gebruikt, moet je class public zijn vermoed ik.
Als je geen lazy loading wilt gebruiken, moet je dit expliciet in je mapping file specifieren.

Waarom wil je trouwens dat je de data in je webpage niet kunt veranderen ? De user mag dus geen gegevens wijzigen ? Vind het wel een beetje raar om dit zo te gaan afdwingen .

Waar mag je die properties wel wijzigen ? Is het dan gewoon geen idee om de setters internal te maken ? (Tenzij je ze wel vanuit een andere DLL mag wijzigen ... )

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Ik meen me te herinneren dat nhibernate public setters / getters vereist.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
whoami schreef op zondag 27 april 2008 @ 09:46:
Kan dit te maken hebben met de lazy loading die NHibernate toepast (vanaf een bepaalde versie dacht ik, is dit default gedrag).
Als NHibernate lazy loading gebruikt, moet je class public zijn vermoed ik.
Als je geen lazy loading wilt gebruiken, moet je dit expliciet in je mapping file specifieren.

Waarom wil je trouwens dat je de data in je webpage niet kunt veranderen ? De user mag dus geen gegevens wijzigen ? Vind het wel een beetje raar om dit zo te gaan afdwingen .

Waar mag je die properties wel wijzigen ? Is het dan gewoon geen idee om de setters internal te maken ? (Tenzij je ze wel vanuit een andere DLL mag wijzigen ... )
Er mogen wel gegevens worden gewijzigd maar dit moet dan via de business laag gaan, in de services class komt dan dus een update functie waarin je de user meestuurd met alle nieuwe waardes, iets als dit wordt het dan:


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
using NHibernate;

namespace Domain.Test
{
    public static class Service
    {
        public static IUser GetById(int userId)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            return session.Get<User>(userId);
        }

        public static void UpdateUser(IUser user, ITheme theme, string name)
        {
            User _user = user as User;

            ISession session = NHibernateHelper.Instance.CurrentSession;
            using (ITransaction transaction = session.BeginTransaction())
            {
                _user.Theme = theme;
                _user.Name = name;
                session.SaveOrUpdate(_user);
                transaction.Commit();
            }
        }
    }
}


Op die manier dwing je af dat alles via de business laag gaat, en dat is precies wat ik wil, jammer dat nhibernate er niet mee om kan gaan :/

Acties:
  • 0 Henk 'm!

  • Ruudjah
  • Registratie: November 1999
  • Laatst online: 06-09 20:58

Ruudjah

2022

DIT BERICHT IS PREVENTIEF VERWIJDERD DOOR DE GEBRUIKER

[ Voor 106% gewijzigd door Ruudjah op 01-12-2009 22:56 ]

TweakBlog


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat is ook een mooie oplossing, ik heb het nu zo

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
37
38
39
40
41
42
43
44
45
namespace Domain.Test 
{ 
    public class User
    { 
        private int id; 
        private string name; 
        private Theme theme; 

        public int Id 
        { 
            get { return id; } 
            internal set { id = value; } 
        } 

        public string Name 
        { 
            get { return name; } 
            internal set { name = value; } 
        } 

        public Theme Theme 
        { 
            get { return theme; } 
            internal set { theme = value; } 
        } 
    } 

    public class Theme
    { 
        private int id; 
        private string name; 

        public int Id 
        { 
            get { return id; } 
            internal set { id = value; } 
        } 

        public string Name 
        { 
            get { return name; } 
            internal set { name = value; } 
        } 
    } 
}


Alle setters staat nu internal bij, ik wist voordat ik dit topic maakte eigenlijk niet dat je modifiers kon toevoegen aan getters en setters anders was ik helemaal nooit met interfaces begonnen. Het lijkt tot nu toe te werken :)

Acties:
  • 0 Henk 'm!

  • Ruudjah
  • Registratie: November 1999
  • Laatst online: 06-09 20:58

Ruudjah

2022

DIT BERICHT IS PREVENTIEF VERWIJDERD DOOR DE GEBRUIKER

[ Voor 90% gewijzigd door Ruudjah op 01-12-2009 22:56 ]

TweakBlog


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ja domain is een apart project :)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Heb je nu al eens gekeken naar dat lazy loading , en dit uitgeschakeld in je hbm files ?
EfBe schreef op zondag 27 april 2008 @ 10:16:
Ik meen me te herinneren dat nhibernate public setters / getters vereist.
Voor properties iig niet. NHibernate werkt ook als je private setters hebt bv (en je kan ook specifieren dat hij de 'properties' niet moet gebruiken, maar rechtstreeks de fields moet accessen).

[ Voor 10% gewijzigd door whoami op 28-04-2008 08:46 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Lazy loading staat volgens de documentatie standaard uit en toen ik bij mijn relatie lazy="true" toevoegde kreeg ik een foutmelding van hibernate die zegt dat het attribuut lazy daar niet thuis hoort en dat klopt ook als ik de documentatie erbij pak.

Mijn set properties zijn overigens allemaal internal op het moment en alles lijkt te werken dus nhibernate vereist niet dat alle getters en setters public zijn :)

[ Voor 14% gewijzigd door Verwijderd op 28-04-2008 11:31 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
EfBe schreef op zondag 27 april 2008 @ 10:16:
Ik meen me te herinneren dat nhibernate public setters / getters vereist.
Het is natuurlijk wel zo, dat, als je ervoor kiest dat NHibernate de members via properties moet initializeren, dat er dan natuurlijk wel een setter moet zijn. Echter, hij mag perfect private zijn, maar hij moet er wel zijn.
(Ik heb er vroeger wel al eens mee gestruggled. Echter, de exceptie die de TS krijgt, doet me denken dat er iets meer aan de hand is ...

https://fgheysels.github.io/

Pagina: 1