Autofac和DI--如何用UnitOfWork解决?

问题描述 投票:0回答:1

我的问题是关于Autofac, UnitOfWork的依赖注入。当我使用AccountService的时候,会出现错误,请问如何解决我的AccountRepository中的DBContext?

DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'uRP.Database.Repository.Account.AccountRepository' can be invoked with the available services and parameters: Cannot resolve parameter 'uRP.Database.Context context' of constructor 'Void .ctor(uRP.Database.Context)'.

我如何解决我的AccountRepository中的DBContext?下面是代码。

RolePlayModule.cs

public class RolePlayModule : Autofac.Module
{
    private readonly IConfiguration _configuration;
    public RolePlayModule(IConfiguration Configuration)
    {
        _configuration = Configuration;
    }

    protected override void Load(ContainerBuilder builder)
    {

        builder.Register(c =>
        {
            var opt = new DbContextOptionsBuilder<Context>();
            opt.UseMySql(_configuration.GetSection("ConnectionStrings:uRP").Value);

            return new Context(opt.Options);
        }).AsImplementedInterfaces().InstancePerLifetimeScope();


        builder.RegisterType<AccountService>().As<IAccountService>();
        builder.RegisterType<AccountRepository>().As<IAccountRepository>();

        builder.RegisterType<Context>().As<DbContext>();
    }
}

在Startup.UnitOfWork.cs中。

            Configuration = new ConfigurationBuilder()
            .SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .Build();


        var builder = new ContainerBuilder();
        builder.RegisterModule(new RolePlayModule(Configuration));

        var container = builder.Build();
        Container = container;

UnitOfWork.cs

    public class UnitOfWork : IUnitOfWork
{
    private Context Context;
    public IAccountRepository AccountRepository { get; }
    public ICharacterRepository CharacterRepository { get; }

    public UnitOfWork(Context context)
    {
        this.Context = context;

        AccountRepository = new AccountRepository(Context);
        CharacterRepository = new CharacterRepository(Context);
    }

    public async Task SaveAsync()
    {
        await Context.SaveChangesAsync();
    }

    public void Save()
    {
        Context.SaveChanges();
    }

    public void Dispose()
    {
        Context.Dispose();
        GC.SuppressFinalize(this);
    }

}

帐户服务.cs

    public class AccountService : IAccountService
{
    private readonly IAccountRepository _unitOfWork;

    public AccountService(IAccountRepository AccountRepository)
    {
        _unitOfWork = AccountRepository;
    }

    public void Dispose()
    {
        _unitOfWork.Dispose();
    }

    public AccountModel FindAccountByName(string accountName)
    {
        return _unitOfWork.FindAccountByName(accountName);
    }

    public async Task<AccountModel> FindAccountByNameAsync(string accountName)
    {
        return await _unitOfWork.FindAccountByNameAsync(accountName);
    }

    public IEnumerable<CharacterModel> GetAccountCharacters(long accountId)
    {
        return _unitOfWork.GetAccountCharacters(accountId);
    }

    public async Task<List<CharacterModel>> GetAccountCharactersAsync(long accountId)
    {
        return await _unitOfWork.GetAccountCharactersAsync(accountId);
    }
}

Context.cs

    public class Context : DbContext
{

    public Context(DbContextOptions<Context> options) : base(options)
    {

    }

    public DbSet<AccountModel> Players { get; set; }
    public DbSet<CharacterModel> Characters { get; set; }


}

ContextDesignTimeFactory.cs

    class ContextDesignTimeFactory : IDesignTimeDbContextFactory<Context>
{
    public Context CreateDbContext(string[] args)
    {
        return Core.Container.Resolve(typeof(Context)) as Context;
    }
}

以及现在的AccountRepository.cs

    public class AccountRepository : IAccountRepository
{
    private Context _context;
    public AccountRepository(Context context)
    {
        _context = context;
    }

    public IEnumerable<CharacterModel> GetAccountCharacters(long accountId)
    {
        return _context.Characters.Where(x => x.gid == accountId);
    }

    public async Task<List<CharacterModel>> GetAccountCharactersAsync(long accountId)
    {
        return await _context.Characters.Where(x => x.gid == accountId).ToListAsync();
    }

    public AccountModel FindAccountByName(string name)
    {
        return _context.Players.FirstOrDefault(x => x.name == name);
    }

    public async Task<AccountModel> FindAccountByNameAsync(string name)
    {
        return await _context.Players.FirstOrDefaultAsync(x => x.name == name);
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

我已经为解析服务做了一个我想要的帮助程序。DependencyHelper.cs

    public static class DependencyHelper
{
    public static T Get<T>()
    {
        return (T)Core.Container.Resolve(typeof(T));
    }
}

现在我想在任何地方都使用这样的程序。

            using (var test = DependencyHelper.Get<IAccountService>())
        {


        }

但我遇到了一个错误,我在上面给你看的... ... 我做错了什么?我找了3天才找到答案...... 谢谢大家的回答

c# dependency-injection autofac
1个回答
0
投票

我知道了。我只是添加了 AsSelf() 到上下文注册。

builder.Register(c =>
            {
                var opt = new DbContextOptionsBuilder<Context>();
                opt.UseMySql("server=localhost;database=uRP;user=root;password=;");

                return new Context(opt.Options);
            }).AsImplementedInterfaces().InstancePerLifetimeScope().AsSelf();
© www.soinside.com 2019 - 2024. All rights reserved.