2009-08-18 31 views
6

Estoy utilizando el julio CTP de .Net RIA Services en una aplicación ASP.Net con algunos componentes de Silverlight. Llamaré a los servicios de RIA de Silverlight..Net RIA Services: DomainService necesita un constructor parameterless?

Mi problema surgió cuando traté de usar Unity y la inyección de dependencia del constructor en mi servicio de dominio (un objeto LinqToEntitiesDomainService). La aplicación Silverlight ahora se queja de no tener un constructor sin parámetros.

No quiero tener un constructor sin parámetros, quiero que Unity resuelva los argumentos del constructor. es posible? ¿Estoy haciendo algo mal? ¿O debería encontrar otra forma de inyectar mis argumentos de constructor?

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

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

    ... 

Aquí está el error que estoy consiguiendo:

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 

Respuesta

12

Puesto que usted tiene un DomainService con un parámetro en su ctor, y necesita más en general, a ser construida a través de algún tipo de contenedor IoC o inyección de dependencias sistema, deberá proporcionar una fábrica de servicio de dominio a nivel de aplicación. Su fábrica es responsable de instanciar el servicio de dominio (y deshacerse de él), y puede hacerlo llamando a otra API, como Unity en su caso.

Aquí hay un ejemplo básico:

En Global.asax.cs de su aplicación, añada lo siguiente:

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(); 
    } 
} 

Espero que ayude!

+0

Lo estaba buscando. Gracias por eso :) – Davita

0

@Brien, supongo que el 'IUserService' depende de IUnitOfWork, donde IUnitOfWork es DashboardEntities?

gusta esta UserRepository:

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

    ... 
} 

Y esto 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; 
    } 

    ... 
} 

estoy usando este diseño. Una cosa que noté es que la clase DashboardEntities se crea más de una vez. La primera vez que lo crea Unity (y solo se creará una vez porque se ha declarado como Singleton en la Configuración de Unity).

Pero la próxima vez, parece que se crea una nueva clase DashboardEntities durante la inicialización desde DomainService (DashboardService)? Esto no es gran cosa porque DomainService no usará este ObjectContext, sino que usará el ObjectContext que Unity inyecta en los Repositorios.

¿Alguien puede confirmar este diseño o mostrar algo más de luz sobre este tema?

Cuestiones relacionadas