.Net RIA Services: DomainService нужен беспараметрический конструктор?

Я использую июльскую CTP-версию .Net RIA Services в приложении ASP.Net с некоторыми компонентами Silverlight. Я звоню в службу RIA из Silverlight.

Моя проблема возникла, когда я попытался использовать Unity и внедрение зависимостей конструктора в моей доменной службе (объект LinqToEntitiesDomainService). Приложение Silverlight теперь жалуется на отсутствие конструктора без параметров.

Я не хочу иметь конструктор без параметров, я хочу, чтобы Unity разрешала аргументы конструктора. Это возможно? Я делаю что-то неправильно? Или мне следует найти другой способ ввести аргументы конструктора?

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

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

    ...

Вот ошибка, которую я получаю:

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

person brien    schedule 18.08.2009    source источник


Ответы (2)


Поскольку у вас есть DomainService с параметром в его ctor, и, как правило, его нужно создавать с помощью какого-то контейнера IoC или системы внедрения зависимостей, вам необходимо предоставить фабрику служб домена на уровне приложения. Затем ваша фабрика отвечает за создание экземпляра службы домена (и ее удаление), и это может быть сделано путем вызова другого API, такого как Unity в вашем случае.

Вот простой пример:

В Global.asax.cs вашего приложения добавьте следующее:

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

Надеюсь, это поможет!

person Nikhil Kothari    schedule 25.08.2009
comment
Я это искал. Спасибо за это :) - person Davita; 21.04.2011

@Brien, я предполагаю, что IUserService зависит от IUnitOfWork, где IUnitOfWork - это DashboardEntities?

Вот как этот репозиторий пользователей:

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

    ...
}

И этот 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;
    }

    ...
}

Я использую этот дизайн. Я заметил одну вещь: класс DashboardEntities создается более одного раза. В первый раз он создается Unity (и будет создан только один раз, потому что он объявлен как Singleton в конфигурации Unity).

Но в следующий раз кажется, что новый класс DashboardEntities создается во время инициализации из DomainService (DashboardService)? В этом нет ничего страшного, потому что DomainService не будет использовать этот ObjectContext, он будет использовать ObjectContext, который вводится Unity в репозитории.

Может ли кто-нибудь подтвердить этот замысел или пролить свет на этот вопрос?

person Stef Heyenrath    schedule 12.08.2010