2009-08-18 13 views
6

Ich verwende das Juli CTP von. Net RIA Services in einer ASP.Net-Anwendung mit einigen Silverlight-Komponenten. Ich rufe die RIA Services von Silverlight an.. NET RIA-Dienste: DomainService benötigt einen Konstruktor ohne Parameter?

Mein Problem entstand, als ich versuchte, die Einheit und Konstruktor Dependency Injection in meinem Domain-Service (ein LinqToEntitiesDomainService Objekt) zu verwenden. Die Silverlight-Anwendung beschwert sich jetzt darüber, keinen parameterlosen Konstruktor zu haben.

Ich will nicht einen parameterlosen Konstruktor haben, ich will Unity die Konstruktorargumente lösen. Ist das möglich? Mache ich etwas falsch? Oder sollte ich einen anderen Weg finden, meine Konstruktorargumente zu injizieren?

public class DashboardService : LinqToEntitiesDomainService<DashboardEntities> 
{ 
    private IUserService userService; 

    public DashboardService(IUserService userService) 
     : base() 
    { 
     if (userService == null) 
     { 
      throw ExceptionBuilder.ArgumentNull("userService"); 
     } 
     this.userService = userService; 
    } 

    ... 

Hier ist der Fehler Ich erhalte:

Webpage error details 

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 
Timestamp: Tue, 18 Aug 2009 14:34:54 UTC 


Message: Unhandled Error in Silverlight 2 Application No parameterless constructor defined for this object. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) 
    at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) 
    at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) 
    at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
    at System.Web.DomainServices.DomainService.DefaultDomainServiceFactory.CreateDomainService(Type domainServiceType, DomainServiceContext context) 
    at System.Web.Ria.DataServiceFactory.GetDataService(HttpContext context) 
    at System.Web.Ria.DataServiceFactory.System.Web.IHttpHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) 
Line: 1 
Char: 1 
Code: 0 
URI: http://dev.localhost/Home 

Antwort

12

Da Sie eine Domainservice mit einem Parameter in seiner Ctor haben, und muss in der Regel durch eine Art von IoC-Container oder Dependency Injection gebaut werden System müssen Sie eine Domain-Service-Factory auf App-Ebene bereitstellen. Ihre Factory ist dann dafür verantwortlich, den Domain-Service zu instanziieren (und zu entsorgen), und zwar durch Aufruf einer anderen API, wie z. B. Unity in Ihrem Fall.

Hier ist ein einfaches Beispiel:

In Global.asax.cs Ihrer Anwendung, fügen Sie folgendes:

public class Global : HttpApplication { 

    static Global() { 
     DomainService.Factory = new MyAppDomainServiceFactory(); 
    } 
} 

internal sealed class MyAppDomainServiceFactory : IDomainServiceFactory { 

    public DomainService CreateDomainService(Type domainServiceType, 
              DomainServiceContext context) { 
     DomainService ds = ... // code to create a service, or look it up 
           // from a container 

     if (ds != null) { 
      ds.Initialize(context); 
     } 
     return ds; 
    } 

    public void ReleaseDomainService(DomainService domainService) { 
     // any custom logic that must be run to dispose a domain service 
     domainService.Dispose(); 
    } 
} 

Hoffnung, das hilft!

+0

Ich suchte danach. Dank dafür :) – Davita

0

@Brien, gehe ich davon aus das 'IUserService' auf IUnitOfWork abhängt, wo die IUnitOfWork die DashboardEntities ist?

Gefällt Ihnen dieses UserRepository:

public class UserRepository : BaseRepository<User>, IUserRepository 
{ 
    protected BaseRepository(IUnitOfWork unitOfWork) 
    { 
    } 

    ... 
} 

Und das IUnitOfWork:

public partial class DashboardEntities : ObjectContext, IUnitOfWork 
{ 
    public const string ConnectionString = "name=DashboardEntities"; 
    public const string ContainerName = "DashboardEntities"; 

    public DashboardEntities() 
     : base(ConnectionString, ContainerName) 
    { 
     this.ContextOptions.LazyLoadingEnabled = true; 
    } 

    ... 
} 

Ich verwende diesen Entwurf. Eine Sache, die ich bemerkte, ist, dass die DashboardEntities Klasse mehr als einmal erstellt wird. Das erste Mal, wenn es von Unity erstellt wird (und nur einmal erstellt wird, weil es in der Unity-Konfiguration als Singleton deklariert ist).

Aber das nächste Mal scheint es, dass eine neue DashboardEntities Klasse während der Initialisierung von der DomainService (DashboardService) erstellt wird? Dies ist keine große Sache, da der DomainService diesen ObjectContext nicht verwenden wird, sondern den ObjectContext, der von Unity in die Repositories injiziert wird.

Kann jemand diesen Entwurf bestätigen oder zu diesem Thema etwas mehr Licht zeigen?