简体   繁体   English

具有泛型类型的Autofac错误

[英]Autofac error with generic type

I have registered some code: 我已经注册了一些代码:

        var stringHelperService = new StringHelperService(new AssemblyService(Assembly.GetExecutingAssembly()));
        var personalSetting = new PersonalSetting(stringHelperService, new PersonalSettingRepository(new XmlRepository(stringHelperService.PersonalSettingFile)));

        var builder = new ContainerBuilder();

        builder.RegisterType<Login>().AsSelf();

        builder.RegisterType<AssemblyService>()
            .As<IAssemblyService>()
            .WithParameter("assembly", Assembly.GetExecutingAssembly());
        builder.RegisterType<XmlRepository>()
            .As<IXmlRepository>()
            .WithParameter("xmlFile", stringHelperService.PersonalSettingFile);

        builder.RegisterType<StringHelperService>().As<IStringHelperService>(); ;
        builder.RegisterType<PersonalSettingRepository>().As<IPersonalSettingRepository>();
        builder.RegisterType<PersonalSetting>().As<IPersonalSettingService>();
        builder.RegisterType<CompanyRepository>().As<ICompanyRepository>();
        builder.RegisterType<CompanyService>().As<ICompanyService>();
        builder.RegisterType<SqlHelperService>().As<ISqlHelperService>();

        var setting = personalSetting.Get();
        var connString = "None";

        if (!string.IsNullOrEmpty(setting.ConnectionString))
            connString = setting.ConnectionString;

        builder.RegisterGeneric(typeof(GenericSQLRepository<>))
            .As(typeof(IGenericSQLRepository<>))
            .WithParameter("context", new MyStoreDataContext(connString))
            .InstancePerLifetimeScope();

        return builder.Build();

I am keeping connectionstring encrypted in a separate xml file, and inject it when it is registered by user. 我将connectionstring字符串加密保存在单独的xml文件中,并在用户注册时将其注入。 But I get an error: 但是我得到一个错误:

> Autofac.Core.DependencyResolutionException occurred
  HResult=0x80131500
  Message=An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = Login (ReflectionActivator), Services = [MyStore_Intranet.Windows.Login], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Container.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context)
   at MyStore_Intranet.App.SetupBootstrapper() in C:\Users\Hans\documents\visual studio 2017\Projects\MyStoreIntranet\MyStore Intranet\App.xaml.cs:line 74
   at MyStore_Intranet.App.OnStartup(StartupEventArgs e) in C:\Users\Hans\documents\visual studio 2017\Projects\MyStoreIntranet\MyStore Intranet\App.xaml.cs:line 28
   at System.Windows.Application.<.ctor>b__1_0(Object unused)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at MyStore_Intranet.App.Main()

> Inner Exception 1:
DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = CompanyService (ReflectionActivator), Services = [MyStore_Intranet.Models.Interfaces.ICompanyService], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope

> Inner Exception 2:
DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = CompanyRepository (ReflectionActivator), Services = [MyStore_Intranet.DataAccess.Interfaces.Interfaces.ICompanyRepository], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope

> Inner Exception 3:
DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyStore_Intranet.DataAccess.SQL.CompanyRepository' can be invoked with the available services and parameters:
Cannot resolve parameter 'MyStore_Intranet.DataAccess.Interfaces.Generic.IGenericSQLRepository`1[MyStore_Intranet.Models.SharedObjects.Company] repository' of constructor 'Void .ctor(MyStore_Intranet.DataAccess.Interfaces.Generic.IGenericSQLRepository`1[MyStore_Intranet.Models.SharedObjects.Company])'.

I do not know what the problem is. 我不知道问题是什么。 I hope you can help me. 我希望你能帮助我。

Edit: On request 编辑:根据要求

public class GenericSQLRepository<T> : ObservableObject<T>, IGenericSQLRepository<T> where T : class, IEntity
{
    private DbSet<T> _dbset;
    private MyStoreDataContext _context;

    public GenericSQLRepository(MyStoreDataContext context)
    {
        _context = context;
        _dbset = _context.Set<T>();
    }

    public async Task<Tuple<bool, IList<T>, Exception>> All()
    {
        try
        {
            return new Tuple<bool, IList<T>, Exception>(true, await _dbset.AsNoTracking().ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> AllNotDeleted()
    {
        try
        {
            return new Tuple<bool, IList<T>, Exception>(true, await _dbset.AsNoTracking().ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> All(Func<IQueryable<T>, IOrderedQueryable<T>> orderby)
    {
        try
        {
            IQueryable<T> dbQuery = _dbset.AsNoTracking();

            if (orderby != null)
            {
                dbQuery = orderby(dbQuery);
            }

            return new Tuple<bool, IList<T>, Exception>(true, await dbQuery.ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> FindBy(Expression<Func<T, bool>> predicate)
    {
        try
        {
            return new Tuple<bool, IList<T>, Exception>(true, await _dbset.AsNoTracking().Where(predicate).ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> FindBy(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IOrderedQueryable<T>> orderby)
    {
        try
        {
            IQueryable<T> dbQuery = _dbset.AsNoTracking();

            if (orderby != null)
            {
                dbQuery = orderby(dbQuery);
            }

            return new Tuple<bool, IList<T>, Exception>(true, await dbQuery.Where(predicate).ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, T, Exception>> FindByKey(Guid id)
    {
        try
        {
            return new Tuple<bool, T, Exception>(true, await _dbset.AsNoTracking().SingleOrDefaultAsync(q => q.ID == id).ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, T, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> AllInclude(params Expression<Func<T, object>>[] includeproperties)
    {
        try
        {
            return new Tuple<bool, IList<T>, Exception>(true, await GetAllIncluding(includeproperties).ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> AllInclude(Func<IQueryable<T>, IOrderedQueryable<T>> orderby, params Expression<Func<T, object>>[] includeproperties)
    {
        try
        {
            return new Tuple<bool, IList<T>, Exception>(true, await GetAllIncluding(orderby, includeproperties).ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> FindByInclude(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeproperties)
    {
        try
        {
            var query = GetAllIncluding(includeproperties);
            return new Tuple<bool, IList<T>, Exception>(true, await query.Where(predicate).ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> FindByInclude(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IOrderedQueryable<T>> orderby, params Expression<Func<T, object>>[] includeproperties)
    {
        try
        {
            var query = GetAllIncluding(orderby, includeproperties);
            return new Tuple<bool, IList<T>, Exception>(true, await query.Where(predicate).ToListAsync().ConfigureAwait(false), null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    private IQueryable<T> GetAllIncluding(params Expression<Func<T, object>>[] includeproperties)
    {
        var queryable = _dbset.AsNoTracking();
        return includeproperties.Aggregate(queryable,
            (q, includeproperty) => (DbQuery<T>)q.Include(includeproperty));
    }

    private IQueryable<T> GetAllIncluding(Func<IQueryable<T>, IOrderedQueryable<T>> orderby, params Expression<Func<T, object>>[] includeproperties)
    {
        IQueryable<T> dbQuery = _dbset.AsNoTracking();

        if (orderby != null)
        {
            dbQuery = orderby(dbQuery);
        }

        return includeproperties.Aggregate(dbQuery, (q, includeproperty) => (DbQuery<T>)q.Include(includeproperty));
    }

    public async Task<Tuple<bool, T, Exception>> Add(T entity)
    {
        try
        {
            _context.Set<T>().Add(entity);
            var result = await _context.SaveChangesAsync().ConfigureAwait(false);
            return result > 0 ? new Tuple<bool, T, Exception>(true, entity, null) : new Tuple<bool, T, Exception>(false, entity, null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, T, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, T, Exception>> Update(T entity)
    {
        try
        {
            _dbset.AddOrUpdate(entity);
            var result = await _context.SaveChangesAsync().ConfigureAwait(false);
            return result > 0 ? new Tuple<bool, T, Exception>(true, entity, null) : new Tuple<bool, T, Exception>(false, entity, null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, T, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, IList<T>, Exception>> Update(List<T> entities)
    {
        try
        {
            foreach (var entity in entities)
            {
                _dbset.AddOrUpdate(entity);
            }

            var result = await _context.SaveChangesAsync().ConfigureAwait(false);
            return result > 0 ? new Tuple<bool, IList<T>, Exception>(true, entities, null) : new Tuple<bool, IList<T>, Exception>(false, entities, null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, IList<T>, Exception>(false, null, ex);
        }
    }

    public async Task<Tuple<bool, T, Exception>> Delete(T entity)
    {
        try
        {
            var objtodelete = _dbset.Find(entity.ID);

            if (objtodelete == null)
                return new Tuple<bool, T, Exception>(false, null, new Exception("Object Is Null Even Though Its Not Supposed Too"));

            _dbset.Remove(objtodelete);
            var result = await _context.SaveChangesAsync().ConfigureAwait(false);
            return result > 0 ? new Tuple<bool, T, Exception>(true, entity, null) : new Tuple<bool, T, Exception>(false, entity, null);
        }
        catch (Exception ex)
        {
            return new Tuple<bool, T, Exception>(false, null, ex);
        }
    }

    public override void Dispose()
    {
        _dbset = null;
        _context = null;
    }
}

public class CompanyRepository : ICompanyRepository
{
    private IGenericSQLRepository<Company> _repository;

    public CompanyRepository(IGenericSQLRepository<Company> repository)
    {
        _repository = repository;
    }

    public async Task<Tuple<bool, Company, Exception>> Add(Company entity)
    {
        return await _repository.Add(entity).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, Company, Exception>> Delete(Company entity)
    {
        return await _repository.Delete(entity).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, Company, Exception>> Update(Company entity)
    {
        return await _repository.Update(entity).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, Company, Exception>> Find(Guid id)
    {
        return await _repository.FindByKey(id).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, IList<Company>, Exception>> All()
    {
        return await _repository.All(q => q.OrderBy(qq => qq.Name)).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, IList<Company>, Exception>> AllNotDeleted()
    {
        return await _repository.FindBy(q => !q.IsDeleted, q => q.OrderBy(qq => qq.Name)).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, IList<Company>, Exception>> AllOwnCompanies()
    {
        return await _repository.FindBy(q => q.IsOwnCompany, q => q.OrderBy(qq => qq.Name)).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, IList<Company>, Exception>> AllOwnCompaniesNotDeleted()
    {
        return await _repository.FindBy(q => !q.IsDeleted && q.IsOwnCompany, q => q.OrderBy(qq => qq.Name)).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, IList<Company>, Exception>> AllExceptOwnCompanies()
    {
        return await _repository.FindBy(q => !q.IsOwnCompany, q => q.OrderBy(qq => qq.Name)).ConfigureAwait(false);
    }

    public async Task<Tuple<bool, IList<Company>, Exception>> AllExceptCompaniesNotDeleted()
    {
        return await _repository.FindBy(q => !q.IsDeleted && !q.IsOwnCompany, q => q.OrderBy(qq => qq.Name)).ConfigureAwait(false);
    }

    public void Dispose()
    {
        _repository = null;
    }
}

I seem to have found the reason. 我似乎已经找到了原因。 To be able to use some search in generic code, I have declared interface IEntity that contains the key. 为了能够在通用代码中使用某些搜索,我声明了包含键的接口IEntity。 The key is in a base class that all models inherits from. 密钥位于所有模型都继承自的基类中。 GenericSqlRepository inherits IEntity, but I forgot to inherit it in base class. GenericSqlRepository继承了IEntity,但是我忘记了在基类中继承它。

DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyStore_Intranet.DataAccess.SQL.CompanyRepository' can be invoked with the available services and parameters:
Cannot resolve parameter 'MyStore_Intranet.DataAccess.Interfaces.Generic.IGenericSQLRepository`1[MyStore_Intranet.Models.SharedObjects.Company] repository' of constructor 'Void .ctor(MyStore_Intranet.DataAccess.Interfaces.Generic.IGenericSQLRepository`1[MyStore_Intranet.Models.SharedObjects.Company])'.

CompanyRepository has a constructor that requires IGenericSQLRepository<Company> , but IGenericSQLRepository<Company> was not registered in Autofac. CompanyRepository具有需要IGenericSQLRepository<Company>的构造函数,但是IGenericSQLRepository<Company>未在Autofac中注册。 If I look at your registration: 如果我查看您的注册信息:

    builder.RegisterGeneric(typeof(GenericSQLRepository<>))
        .As(typeof(IGenericSQLRepository<>))
        .WithParameter("context", new MyStoreDataContext(connString))
        .InstancePerLifetimeScope();

you register it As(typeof(IGenericSQLRepository<>))) , but I think you need AsClosedTypesOf(...) : 您将其注册As(typeof(IGenericSQLRepository<>))) ,但是我认为您需要AsClosedTypesOf(...)

    builder.RegisterGeneric(typeof(GenericSQLRepository<>))
        .AsClosedTypesOf(typeof(IGenericSQLRepository<>))
        .WithParameter("context", new MyStoreDataContext(connString))
        .InstancePerLifetimeScope();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM