I am new to .NET. I am create a internet shop but i have a problems
My Error:
Error activating IBookRepository No matching bindings are
available, and the type is not self-bindable. Activation path: 2)
Injection of dependency IBookRepository into parameter repo of
constructor of type BooksController 1) Request for BooksController
Suggestions: 1) Ensure that you have defined a binding for
IBookRepository. 2) If the binding was defined in a module, ensure
that the module has been loaded into the kernel. 3) Ensure you have
not accidentally created more than one kernel. 4) If you are using
constructor arguments, ensure that the parameter name matches the
constructors parameter name. 5) If you are using automatic module
loading, ensure the search path and filters are correct.
I using 3 project in Solution I have a interface IBookRepository in c# Class Library Domain and using asp.net mvc in controller
IBookRepository:
using Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Abstract
{
public interface IBookRepository
{
IEnumerable<Book> Books { get; }
}
}
BooksController:
using Domain.Abstract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebUI.Controllers
{
public class BooksController : Controller
{
private IBookRepository repository;
public BooksController(IBookRepository repo)
{
repository = repo;
}
public ViewResult List()
{
return View(repository.Books);
}
}
}
I have a bindings for all the constructor parameter types:
private static void RegisterServices(IKernel kernel)
{
System.Web.Mvc.DependencyResolver.SetResolver(new WebUI.Infrastructure.NinjectDependencyResolver(kernel));
}
How can I fix this problem?
So you have the first step of dependency injection down, but you need to tell your code what concrete class to use when your interface is requested. To do that you need to create a binding for your concrete class.
To do this you need to navigate to your Ninject bindings file and add this:
Bind<IBookRepository>().To<NameOfYourClassThatImplementsIBookRepository>();
Obviously NameOfYourClassThatImplementsIBookRepository should be replaced with the actual name of your concrete class (i.e the class that implements your interface).
I am not aware of Ninject, but looking at the code above, BookController constructor needs an instance of class which implements IBookRepository. Think of constructor chaining or have one more default constructor to pass instance to above written constructor.
using Domain.Abstract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebUI.Controllers
{
public class BooksController : Controller
{
private IBookRepository repository;
public BooksController():this(new BookRepository())
{
}
public BooksController(IBookRepository repo)
{
repository = repo;
}
public ViewResult List()
{
return View(repository.Books);
}
}
}
Related
I am trying to learn design patterns in C# and my friend has written me some code for an Abstract factory pattern (I think).
from what I am seeing the code creates a factory(Fa),
this factory(Fa) then creates another factory(Fb) based on an Enum and then that factory(Fb) creates a concrete class that can be used to call an API etc.
I can create a factory(Fb) and it creates the class but when I call methods from the class that were created by the factory(fb), I do not see my methods and cant call them but can only call the class that it inherits.
What I am trying to do in a nutshell, is create a factory that creates Jane dolls (like it does) and this inherits everything from the doll class, it also has all its own properties, great, but why cant I access its own properties when I make a factory to create the Jane Factory, it only lets me use the inherited Doll methods this way, but if I created another factory to create Santa dolls it would have different methods I need to use.
**Web.Controllers
**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Qqq.Dolls.Web.Controllers
{
public class InventoryController : Controller
{
private readonly IDollFactory _dollFactory;
private readonly IJaneDollFactory _janeDollFactory;
private readonly IMapper _mapper;
public InventoryController(IJaneDollFactory dollFactory, IMapper mapper, IDollFactory dollFactory1)
{
_janeDollFactory = dollFactory;
_mapper = mapper;
_dollFactory = dollFactory1;
}
public async Task<IActionResult> List()
{
var token = HttpContext.Session.GetObject<OAuthResponse>(SessionConstants.JaneToken);
var doll = _JaneDollFactory.Create(token, JaneScopeConstants.GetAllScopes());
var a = _DollFactory.Create(Doll.Jane, HttpContext);
var ab = await a.LGetProductAsync("TestProduct");
var inventory = await doll.GetInventory();
var ret = inventory.InventoryItems.Select(
inventoryItem => _mapper.Map<InventoryViewModel>(inventoryItem));
return View(ret);
}
}
}
DollFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Qqq.Dolls.Web.Infrastructure;
public class DollFactory : IDollFactory
{
private readonly IJaneDollFactory _JaneDollFactory;
public DollFactory(IJaneDollFactory JaneDollFactory)
{
_JaneDollFactory = JaneDollFactory;
}
public IDoll Create(Doll Doll, HttpContext httpContext)
{
switch (Doll)
{
case Doll.Jane:
var token = httpContext.Session.GetObject<OAuthResponse>(SessionConstants.JaneToken);
return _JaneDollFactory.Create(token, JaneScopeConstants.GetAllScopes());
default:
throw new NotImplementedException();
}
}
}
IJaneDollFactory Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Qqq.Dolls.Jane;
public interface IJaneDollFactory
{
IJaneDoll Create(OAuthResponse oAuthResponse, List<string> scopes, HttpMessageHandler httpMessageHandler = null);
}
**IJaneDoll interface **
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Qqq.Dolls.Jane;
public interface IJaneDoll : IDoll
{
//Inventory
Task<Inventory> GetInventory();
Task ListInventoryItem(InventoryItem product);
Task DeleteInventoryItem(string sku);
}
IDoll interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public interface IDoll
{
Task ListProductAsync(Product product);
Task<Product> GetProductAsync(string productId);
}
interface IDollFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Qqq.Dolls.Web.Infrastructure;
public interface IDollFactory
{
IDoll Create(Doll doll, HttpContext httpContext);
}
JaneDollFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Qqq.Dolls.Jane;
public class JaneDollFactory : IJaneDollFactory
{
private readonly IMapper _mapper;
private readonly JaneApiConfiguration _JaneApiConfiguration;
public JaneDollFactory(IOptions<JaneApiConfiguration> JaneApiConfiguration, IMapper mapper)
{
_mapper = mapper;
_JaneApiConfiguration = JaneApiConfiguration.Value;
}
public IJaneDoll Create(OAuthResponse oAuthResponse, List<string> scopes, HttpMessageHandler httpMessageHandler = null)
{
return new JaneDoll(_mapper, _JaneApiConfiguration, oAuthResponse, scopes, httpMessageHandler);
}
}
This is happening is because in you factory create method you have the return type as
IDoll
So when you create a doll, no matter what doll you instantiate, it gets implicitly casted into an IDoll (this is the mistake in DollFactory class)
Since your caller knows what doll it wants the abstract factory to create, when you retrieve the object you can explicitly cast it to an IJaneDoll
var a = (IJaneDoll) _DollFactory.Create(Doll.Jane, HttpContext);
This should allow you to access members from both IDoll and IJane doll.
I am using Entity Framework Core. I want to create an async method which will create new user in my database, i have included all the libraries I need, but some methods that are supposed to work with database are missing, I have almost every async method but i am missing AddAsync and RemoveAsync. When I type AddAsync manually I get the following error message: "Error CS1061 'DbSet' does not contain a definition for 'AddAsync' and no accessible extension method 'AddAsync' accepting a first argument of type 'DbSet' could be found (are you missing a using directive or an assembly reference?)"
The class where the method is created has following code and libraries included:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data;
using Microsoft.EntityFrameworkCore;
namespace ClassLibrary
{
public class Class1 : Interface1
{
public async Task AddKorisnik(Korisnici k)
{
using (ExtentEntities context = new ExtentEntities())
{
context.Korisnici.AddAsync();
await context.SaveChangesAsync();
}
}
}
}
The class where the DbContext is used is following:
namespace ClassLibrary
{
using System;
using System.Linq;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class ExtentEntities : DbContext
{
public ExtentEntities()
: base("name=ExtentEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Korisnici> Korisnici { get; set; }
}
}
There is nothing asynchronous with adding an object to an in-memory DbSet<T>. You should use the synchronous Add method to do this.
SaveChangesAsync() is the method that actually connects asynchronously to the underlying database.
I'm writing various class libraries (tools and helpers) for my future ASP.Net project.
Right now my solution doesn't have web project, but it's not supposed to be a problem.
I added reference to System.Web to project and now I able to access HttpContext in code.
Below my code for resource manager class that suppose to get application global resources:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace ResourceManager
{
public class ResourceManager : IResourceManager
{
HttpContext context;
public ResourceManager(HttpContext ctx)
{
context = ctx;
}
public string GetError(string key)
{
return context.GetGlobalResourceObject("Errors", key).ToString();
}
//And so on........
}
}
But unfortunately Visual Studio intellisense can't find GetGlobalResourceObject.
Hitting F12 and I can see this static function inside HttpContext class.
After running build I'm getting this error message:
Member 'HttpContext.GetGlobalResourceObject(string, string)' cannot be accessed with an instance reference; qualify it with a type name instead
It's strange behaviour and interesting for me why it's happening.
Thanks for help
This is untested, but from the error message I think the usage should be as below.
Essentially you just use the static HttpContext rather than creating an instance of it.
using System.Web;
namespace ResourceManager
{
public class ResourceManager : IResourceManager
{
public string GetError(string key)
{
return HttpContext.GetGlobalResourceObject("Errors", key).ToString();
}
//And so on........
}
}
I wish for structuremap to scan my assemblies and register classes as singletons.
I'd further restrict this to factories, services etc.
For now, however, the challenge is to mark the found registrations as singletons.
I've found out that one way is through conventions.
I've found an example that marks a single, specific registration as singleton, but I want to do it for all registrations.
The example code does not compile; first of all because the IsConcrete etc is not available.
Does anyone have a way forward?
using StructureMap;
using StructureMap.Configuration.DSL;
using StructureMap.Graph;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace planner_gui
{
public class SingletonConvention : IRegistrationConvention
{
public void Process(Type t, Registry registry)
{
if (!(t.IsConcrete()) || !(t.CanBeCreated()) ) return;
registry.For( ... ).Singleton().Use(t);
}
}
public class GuiRegistry : Registry
{
public GuiRegistry()
{
Scan(x =>
{
x.AssemblyContainingType<IExecutionContext>();
x.With(new SingletonConvention());
});
}
}
}
IsConcrete() method is an extension method in StructureMap.TypeRules namespace so adding
using StructureMap.TypeRules
would do the trick.
A bit rusty here with regards to WCF Services.
I have a custom class named cSecurity.cs which does some custom functions.
I want to use this custom class inside my Service:
This is the App.svc.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace AppServices
{
public class App : IApp
{
public cSecurity _csec;
public string GetItems(int agentID, string agentName)
{
// Need to use some functions from the cSecurity class here???
return _csec.getItems();
}
}
}
This is the cSecurity.cs class:
using System.Collections;
using System.Configuration;
using System.Net;
namespace AppServices
{
public class cSecurity
{
// Some functions defined here....
public string getItems(){
return string.Empty;
}
}
}
But I am getting an error on the line:
public cSecurity _csec;
"The type or namespace name 'cSecurity' could not be found."
This seems pretty trivial but I seem to be lost here.
Appreciate any insight. Thanks.
For some reason, the solution for this was for me to close and restart VS. Not sure what caused the class for it to be not referenced by VS.