Разрешение службы в конструкторе без параметров вызывает InvalidOperationException в репозитории - PullRequest
0 голосов
/ 14 мая 2018

У меня есть собственный класс SiteRole, который наследует RoleProvider. Я внедряю IUserService в конструктор, чтобы выполнить запрос для получения всех ролей.

Он продолжал выдавать ошибку, что класс SiteRole нуждался в конструкторе без параметров. В итоге я ввел IUserService так:

public SiteRole()
{
    _userService = DependencyResolver.Current.GetService<IUserService>();
}

Внутри класса я переопределяю функцию GetRolesForUser

public override string[] GetRolesForUser(string nickname)
{
    return new string[] { _userService.GetRoleForUser(nickname) };
}

UserService вызывает этот запрос LINQ в UserRepository (в этой строке выдается System.InvalidOperationException: «Операция не может быть завершена, поскольку удален DbContext.»)

public string GetRoleForUser(string nickname)
{
    return DbContext.Users.Where(u => u.Nickname == nickname).FirstOrDefault().Role.Name;
}

Есть какие-нибудь подсказки, как я могу решить эту проблему? Вы не можете внедрить зависимости в RoleProvider через конструктор, поэтому я должен использовать DependencyResolver.Current.GetService ().

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Я решил проблему следующим образом:

virtual Owned<IUserService> ResolveUserService()
=> DependencyResolver.Current.GetService<Owned<IUserService>>();

И вызвать службу в методе GetRolesForUser с помощью оператора Using:

public override string[] GetRolesForUser(string nickname)
    {
        using(var userService = ResolveUserService())
        {
            return new string[] {userService.Value.GetRoleForUser(nickname) };

        }
    }

На sidenote DbContext создается в RepositoryBase. Я использую шаблон общего репозитория для своего проекта.

 public abstract class RepositoryBase<T> where T : class
{

    #region properties

    private StoreEntities dataContext;
    private readonly IDbSet<T> dbSet;

    protected IDbFactory DbFactory
    {
        get;
        private set;
    }

    protected StoreEntities DbContext
    {
        get { return dataContext ?? (dataContext = DbFactory.Init()); }
    }

    #endregion

    protected RepositoryBase(IDbFactory dbFactory)
    {
        DbFactory = dbFactory;
        dbSet = DbContext.Set<T>();
    }


    #region Implementation of defaults

    public virtual void Add(T entity)...........

Спасибо за помощь!

0 голосов
/ 14 мая 2018

Похоже, у вашего SiteRole класса срок жизни больше, чем у введенного IUserService. Вы должны проверить, действительно ли это источник проблем, и настроить время жизни зарегистрированных сервисов с помощью API-интерфейса контейнера DI. Вот несколько ссылок для различных контейнеров: Autofac , NInject , Unity , Простой инжектор .

И, возможно, немного измените тип SiteRole & mdash; используйте свойство, чтобы получить в живых UserService вместо поля, с помощью которого создается единственный экземпляр во время SiteRole создания экземпляра.

public SiteRole()
{
    // this field should be removed
    // _userService = DependencyResolver.Current.GetService<IUserService>();
}

// this property should be used instead of field
private IUserService UserService 
{
    get { DependencyResolver.Current.GetService<IUserService>(); }
}

Или в современном синтаксисе

private IUserService UserService => DependencyResolver.Current.GetService<IUserService>();

Но будьте осторожны и убедитесь, что вы не получите неконтролируемое количество созданных UserService экземпляров, если оно, например, настроено как экземпляр на вызов в вашем контейнере DI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...