it-swarm.dev

Denetleyicide parametresiz bir genel yapıcı hatası olduğundan emin olun

DbContext'ımı ek bir kurucuya sahip olacak şekilde değiştirinceye kadar harika çalışan bu öğreticiyi izledim. Şimdi kararla ilgili sorunlar yaşıyorum ve bunu düzeltmek için ne yapacağımdan emin değilim. Parametresiz kurucuyu almaya zorlamanın kolay bir yolu var mı, yoksa yanlış mı yaklaşıyorum? 

İki yapıcı ile DbContext:

public class DashboardDbContext : DbContext
{
    public DashboardDbContext() : base("DefaultConnection") { }

    public DashboardDbContext(DbConnection dbConnection, bool owns)
        : base(dbConnection, owns) { }
}

SiteController yapıcı:

private readonly IDashboardRepository _repo;

public SiteController(IDashboardRepository repo)
{
    _repo = repo;
}

Depo:

DashboardDbContext _context;

public DashboardRepository(DashboardDbContext context)
{
    _context = context;
}

UnityResolver code:

public class UnityResolver : IDependencyResolver
{
    private readonly IUnityContainer _container;

    public UnityResolver(IUnityContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return _container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return _container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = _container.CreateChildContainer();
        return new UnityResolver(child);
    }

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

WebApiConfig:

var container = new UnityContainer();
container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);

WebApi Çağrısından Hata:

System.InvalidOperationException: 'SiteController' türünde bir denetleyici oluşturmaya çalışırken bir hata oluştu. Denetleyicinin parametresiz bir kamu kurucusu olduğundan emin olun.

at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) 
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) 
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()

InnerException: System.ArgumentException: 'Dashboard.Web.Controllers.SiteController' yazdığınızda, varsayılan bir kurucu yoktur.

at System.Linq.Expressions.Expression.New(Type type) 
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

Öğretici harikaydı ve ikinci kurucuyu ekleyene kadar benim için iyi çalışıyor.

86
scarpacci

Olan şu ki, bu sorun tarafından ısırıldığınızdan . Temel olarak, olan şey, denetleyicilerinizi açıkça kapsayıcınıza kaydetmemenizdir. Birlik, sizin için kayıtlı olmayan somut türleri çözmeye çalışıyor, ancak çözemediği için (yapılandırmanızdaki bir hata nedeniyle) boşa dönüyor. Null döndürmek zorundadır, çünkü Web API bunu IDependencyResolver sözleşmesi nedeniyle yapmaya zorlar. Unity boş döndürdüğünden, Web API denetleyicinin kendisini oluşturmaya çalışır, ancak varsayılan bir kurucu olmadığı için "Denetleyicide parametresiz bir genel kurucu olduğundan emin olun" istisnasını atar. Bu istisna mesajı yanıltıcıdır ve asıl nedeni açıklamamaktadır.

Denetleyicilerinizi açıkça kaydettiyseniz, daha net bir istisna mesajı göreceksiniz ve bu yüzden tüm kök türlerini her zaman açıkça kaydetmelisiniz.

Fakat elbette, yapılandırma hatası sizden ikinci kurucunuzu DbContext'nuza eklemenizi sağlar. Birlik her zaman en fazla argümanla yapıcıyı seçmeye çalışır, ancak bu belirli kurucuyu nasıl çözeceğine dair hiçbir fikri yoktur.

Bu yüzden asıl sebep, DbContext dosyasını oluşturmak için Unity'nin otomatik kablolama yeteneklerini kullanmaya çalışıyor olmanızdır. DbContext, otomatik olarak bağlanmaması gereken özel bir türdür. Bu bir çerçeve türüdür ve bu nedenle fabrika delegesi kullanarak onu kaydettirmek için geri dönmelisiniz:

container.Register<DashboardDbContext>(
    new InjectionFactory(c => new DashboardDbContext())); 
111
Steven

Benim durumumda, enjekte edilen bağımlılığımın kurucusundaki bir istisna vardı (örneğinizde - DashboardRepository yapıcısının içinde). İstisna, MVC altyapısı içinde bir yerlerde kalmıştı. İlgili yerlere günlük ekledikten sonra buldum.

36
Illidan

Aynı sorunu yaşadım ve UnityConfig.cs dosyasında değişiklik yaparak sorunu çözdüm UnityConfig.cs dosyasındaki bağımlılık sorununu çözmek için eklemeniz gerekenler:

public static void RegisterComponents()    
{
    var container = new UnityContainer();
    container.RegisterType<ITestService, TestService>();
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
5
user1407955

Bazen, arabiriminizi ContainerBootstraper.cs içinde çözdüğünüz için hatayı yakalamak çok zordur. Benim durumumda api kontrolöre enjekte ettiğim arayüzün uygulanmasında bir hata oluştu. Hatayı bulamadım çünkü bootstraperContainer'daki arayüzü bu şekilde çözdüm: container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
sonra bootstrap konteynerime şu satırı ekledim: container.RegisterType<MyController>(); bu yüzden projeyi derlerken derleyici şikayet etti ve yukarıdaki satırda durdu ve hatayı gösterdi. 

4
Amir978

Ben de aynı problemi yaşadım. İki gün boyunca googledim. En sonunda yanlışlıkla sorunun Denetleyicinin kurucusunun erişim değiştiricisi olduğunu fark ettim . Denetleyicinin kurucusunun arkasındaki public anahtar Word'ü yazmadım.

public class MyController : ApiController
    {
        private readonly IMyClass _myClass;

        public MyController(IMyClass myClass)
        {
            _myClass = myClass;
        }
    }

Bu deneyimi başka bir cevap olarak ekledim, belki de başkası benzer bir hata yaptı.

1
Bobs

Yanlışlıkla UnityContainer içinde tanımladığım arabirim türü yerine bir özelliği belirli bir nesne türü olarak tanımladığımda bu hatayı aldım.

Örneğin:

UnityContainer'ı Tanımlama:

var container = new UnityContainer();
container.RegisterInstance(typeof(IDashboardRepository), DashboardRepository);
config.DependencyResolver = new UnityResolver(container);

SiteController (yanlış yol - bildirim repo tipi):

private readonly DashboardRepository _repo;

public SiteController(DashboardRepository repo)
{
    _repo = repo;
}

SiteController (doğru yol):

private readonly IDashboardRepository _repo;

public SiteController(IDashboardRepository repo)
{
    _repo = repo;
}
0
MasterPiece

Denetleyicinizde bir arayüz varsa

public myController(IXInterface Xinstance){}

Bunları Bağımlılık Enjeksiyon konteynerine kaydetmelisiniz.

container.Bind<IXInterface>().To<XClass>().InRequestScope();
0
Ahmet Arslan

Türünüzü aşağıdaki gibi eşleştirmek için nityConfig.cs kullanıyorsanız.

public static void RegisterTypes(IUnityContainer container)
    {
     container.RegisterType<IProductRepository, ProductRepository>();
    }

Container hakkında **webApiConfig.cs** hakkında bilgi vermelisin.

config.DependencyResolver = new Unity.AspNet.WebApi.UnityDependencyResolver(UnityConfig.Container);
0
Vinay Patel