Question

I am now doing a dynamic query in my project by using System.Linq.Dynamic. I use Autofac as my default IOC container. But Now I get a problem on registering generic components, here is my code :

the interface:

public interface IDynamicQuery
{
    IQueryable<T> CreateDynamicQuery<T>(string propertyName, string propertyValue, Expression<Func<T, bool>> where) where T:class;
}

the class:

public class DynamicQuery :IDynamicQuery
{
    public DynamicQuery(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
    }
    private  readonly IUnitOfWork unitOfWork;

    public IQueryable<T> CreateDynamicQuery<T>(string propertyName, string propertyValue, Expression<Func<T, bool>> where) where T:class
    {
        var appRepository = unitOfWork.Repository<T>();

        IQueryable<T> queryResult = null;
        if (propertyName.Contains('$'))  
            propertyName = propertyName.Replace('$', '.');
        queryResult = appRepository.GetMany(where).Where("" + propertyName + ".Contains(\"" + propertyValue + "\")");
        return queryResult;
    }
}

Then I register them in the application start entry:

builder.RegisterType<IDynamicQuery>().As<DynamicQuery>().InstancePerHttpRequest();

But When I start up my project based on MVC 4, it throws me an exception like :

 The type 'TinyFrame.Framework.Query.IDynamicQuery' is not assignable to service 'TinyFrame.Framework.Query.DynamicQuery'.

the Exception throws at : var container = builder.Build();

I know how to register a generic class in autofac, but I don't know how to register above class I raised, anyone can help me on this? I am a new comer to autofac, thx in advice.

Was it helpful?

Solution

@CharlieShi I had the same problem and I noticed that I was forgetting to add inheritance to my class. But in your case, try this:

builder.RegisterType<DynamicQuery>().As<IDynamicQuery>().InstancePerHttpRequest();

reverse the interface with the class!

OTHER TIPS

In my case, I had reversed the order in which the interface and the classes are to be mentioned:

builder.RegisterType<CONCRETE_CLASS>().As<INTERFACE>();

This can be done if you forget to add the Interface to your class.

builder.RegisterType<People>().As<IPeople>();

This will cause the error

public class People

This will resolve it

public class People : IPeople 

You can register the complete assembly with autofac container like this way:

 builder.RegisterAssemblyTypes(
            typeof(YourClass).Assembly)
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();

In your case, if you want to register the perticular type only, then just use the following:

builder.RegisterType<DynamicQuery>()
             .As<IDynamicQuery>()
             .InstancePerLifetimeScope();

You can set the lifetime according to your business requirements.

Your problem is that you try to map interface on implementation, just swap IDynamicQuery and DynamicQuery. And don't forget to make a rebuild.

It should be like:

builder.RegisterType<DynamicQuery>().As<IDynamicQuery>().InstancePerHttpRequest();

Encountered the same problem but the cause was different in my case. I didn't see that I was registering the same type twice. I find this error message is misleading.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top