user1428798
user1428798

Reputation: 1546

Autofac dependency resolution error

I have a class

 public interface IDbContext : IDisposable
{
    IDbConnection Connection { get; }

    IDbTransaction CreateOpenedTransaction();

    IEnumerable<T> ExecuteProcedure<T>(string procedure, dynamic param = null, IDbTransaction transaction = null);

    int ExecuteProcedure(string procedure, dynamic param = null, IDbTransaction transaction = null);
}

this is the implementation:

 public sealed class DbContext : IDbContext
{
    private bool disposed;
    private SqlConnection connection;

    public DbContext(string connectionString)
    {
        connection = new SqlConnection(connectionString);
    }

    public IDbConnection Connection
    {
        get
        {
            if (disposed) throw new ObjectDisposedException(GetType().Name);

            return connection;
        }
    }

    public IDbTransaction CreateOpenedTransaction()
    {
        if (connection.State != ConnectionState.Open)
            Connection.Open();
        return Connection.BeginTransaction();
    }

I try to resolve dependance with autofac like this:

public class RepositoryBaseTest { private static IContainer _container;

    [TestInitialize]
    public virtual void TestInitialize()
    {
        var builder = new ContainerBuilder();

        builder.RegisterAssemblyTypes(typeof(ICommandHandler<object>).Assembly)
               .AsImplementedInterfaces()
               .SingleInstance();

        builder.RegisterAssemblyTypes(typeof(IQuery<object>).Assembly)
              .AsImplementedInterfaces()
              .SingleInstance();

        builder.RegisterAssemblyTypes(typeof(IQueryMultiple<object>).Assembly)
              .AsImplementedInterfaces()
              .SingleInstance();

        builder.Register<IMemberRepository>(c =>
        new MemberRepository(
            c.Resolve<IDbContext>()))
        .SingleInstance();

        builder.Register<IDbContext>(c =>
          new DbContext(ConfigurationManager.ConnectionStrings["Speed"].ConnectionString))
          .Named<IDbContext>("Speed")
          .InstancePerDependency();

      _container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(_container));
    }

    #region Resolve

    protected void ExecuteCommand<T>(T command)
    {
        _container.Resolve<ICommandHandler<T>>().Execute(command);
    }

    protected IEnumerable<T> Query<T>(Func<T, bool> condition)
    {
        return _container.Resolve<IQueryMultiple<T>>().Where(condition);
    }

    protected T Select<T>(Func<T, bool> condition)
    {
        return _container.Resolve<IQuery<T>>().Select(condition);
    }

    protected T Resolve<T>()
    {
        return _container.Resolve<T>();
    }

    #endregion
}

and in the class test, i try to test:

   public class MemberRepositoryTest : RepositoryBaseTest
{
    private IMemberRepository _memberRepository;

    [TestInitialize]
    public override void TestInitialize()
    {
        base.TestInitialize();
        _memberRepository = new MemberRepository(Resolve<IDbContext>());
    }

but i catch an error in this instruction:_memberRepository = new MemberRepository(Resolve());

The requested service 'IDbContext' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

How can i resolve this?

Upvotes: 0

Views: 2025

Answers (1)

Memoizer
Memoizer

Reputation: 2279

Solution 1. You are registered a IDbContext as Named service.

.Named<IDbContext>("Speed")

Thus, you must use a ResolveNamed method.

_container.ResolveNamed<IDbContext>("Speed");

Solution 2. You can just register a IDbContext as a type. In this case, the method Resolve() should work correctly.

builder.Register<IDbContext>(c =>
          new DbContext(ConfigurationManager.ConnectionStrings["Speed"].ConnectionString))
          .InstancePerDependency();

Upvotes: 0

Related Questions