DbContext and Autofac - c#

I have problem with registration of System.Data.Entity.DbContext in Autofac.
Constructors of my classes are:
public DeviceService(IDevice device)
{
_device = device;
}
public Device(DbContext con)
{
_localDb = con;
}
I tried this :
_container = new ContainerBuilder();
_container.RegisterType<DbContext>().As<DbContext>().InstancePerLifetimeScope();
_container.RegisterType<Device>().As<IDevice>();
_container.RegisterType<DeviceService>().As<IDeviceService>();
_dependencyContainer = _container.Build();
But It didn't work because when I tried resolve _dependencyContainer.Resolve<IDeviceService>(), I got this exception:
An exception of type 'Autofac.Core.DependencyResolutionException'
occurred in Autofac.dll but was not handled in user code
Additional information: An exception was thrown while activating
WpfApplication2.DeviceService -> WpfApplication2.Device ->
System.Data.Entity.DbContext.
I can't find solution in Google. What is the solution ?

I found out that injection of System.Data.Entity.DbContext by Autofac is imposible. But you can inject inherited object of that DbContext -> MyContext: DbContext ->
_container.RegisterType<MyContext>().AsSelf()

Related

An error occurred during the activation of a particular registration while using Autofac

This is the way we register the classes using Autofac
builder.Register(c => new FileLogger(ILogger)).As<ILogger>().SingleInstance();
var sizeinkb= Convert.ToInt32(configuration.GetValue<string>("Settings:SizeInKb"));
builder.RegisterType<Broker>().As<IBroker>().WithParameter("size", sizeinkb).SingleInstance();
builder.RegisterType<MainClass>().As<IMainClass>().SingleInstance();
var container = builder.Build();
ContainerFactory.SetContainer(container);
Here is our class
public class MainClass:IMainClass
{
public MainClass(IBroker broker,ILogger logger)
{
_broker = broker,
_logger = logger
}
}
Here is the broker class
public class Broker:IBroker
{
public Broker(ILogger logger,
int size)
{
}
}
Autofac.Core.DependencyResolutionException
HResult=0x80131500
Message=An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = MainClass (ReflectionActivator), Services = [MyProject.IMainClass], Lifetime = Autofac.Core.Lifetime.RootScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyProject.MainClass' can be invoked with the available services and parameters:
Cannot resolve parameter 'MyProject.IBroker broker' of constructor 'Void .ctor(MyProject.IBroker, MyProject.ILogger)'.
Here is another approach where the dependencies can be resolved during the lambda setup
//...removed for brevity
var sizeinkb = Convert.ToInt32(configuration.GetValue<string>("Settings:SizeInKb"));
builder.Register(c => new Broker(c.Resolve<ILogger>(), sizeinkb))
.As<IBroker>().SingleInstance();
builder.RegisterType<MainClass>().As<IMainClass>().SingleInstance();
var container = builder.Build();
ContainerFactory.SetContainer(container);

How can I resolve a component that has been registered with a keyed filter argument in the constructor?

I have a concrete class implementation of my service interface like the following:
public class MyService:IService {
public MyService([KeyFilter("sampleone")] IRepository repoToUse) {
_repoToUse = repoToUse;
}
// rest of code
}
I am registering the service as:
builder.Register(ctx => new CustomRepo()).Keyed<IRepository>("sampleone");
builder.RegisterType<MyService>().AsSelf().WithAttributeFiltering();
In my controller, I am using the lifetime scope to resolve the services.
public class MyTestController:ApiController{
public MyTestController(ILifteTimeScope scope) {
var testone = scope.Resolve(typeof(IService));
var testtwo = scope.Resolve(typeof(MyService));
}
}
So I'm resolving these services and I am able to resolve "testone" properly but when the application tries to resolve "testtwo", it throws an error: Autofac.Core.DependencyResolutionException. It essentially states that I am unable to resolve the IRepository.
Why is this occurring?
I derped and this is working.
I registered the type later on during the process as self() but without attribute filtering so it overwrote the earlier registrations.
e.g.
// later on in the execution path.
builder.RegisterType<MyService>().As<IServiceTwo>.AsSelf();

IFacebookManager, is an interface and cannot be constructed. Are you missing a type mapping?

I tried to do something like login with facebook in xamarin forms but i have Excpetion in constructor while app is loading
This is my code
private readonly INavigationService _navigateService;
private readonly IFacebookManager _facebookManager;
private readonly IPageDialogService _dialogService;
and In Constructor
public LoginPageViewModel(INavigationService navigationService, IPageDialogService dialogService , IFacebookManager facebookManager)
{
_dialogService = dialogService;
_facebookManager = facebookManager;
_navigateService = navigationService;
IsLogedIn = false;
}
but i got this exception and i don't know why
Unity.Exceptions.ResolutionFailedException: Resolution of the dependency failed, type = 'System.Object', name = 'LoginPage'.
Exception occurred while: Calling constructor LGMobileApp.Views.LoginPage().
Exception is: ResolutionFailedException - Resolution of the dependency failed, type = 'LGMobileApp.ViewModels.LoginPageViewModel', name = '(none)'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, LGMobileApp.Helpers.IFacebookManager, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving LGMobileApp.ViewModels.LoginPageViewModel,(none)
Resolving parameter 'facebookManager' of constructor LGMobileApp.ViewModels.LoginPageViewModel(Prism.Navigation.INavigationService navigationService, Prism.Services.IPageDialogService dialogService, LGMobileApp.Helpers.IFacebookManager facebookManager)
Resolving LGMobileApp.Helpers.IFacebookManager,(none)
-----------------------------------------------
At the time of the exception, the container was:
Resolving LGMobileApp.Views.LoginPage,LoginPage (mapped from System.Object, LoginPage)
Resolving LGMobileApp.Views.LoginPage,LoginPage
Calling constructor LGMobileApp.Views.LoginPage()
In my app.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<LoginPage>();
}
Any help ?
While Prism does ensure that each container will resolve a concrete type for you as this is required to resolve your ViewModel, none of the containers can resolve an interface without a registration.
Any implementation that is available in your shared code can be done in your App.RegisterTypes like:
public class App : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IFacebookService, FacebookService>();
}
}
If your implementation type is platform specific then you would need to add something like this to each of your platform projects like iOS, Android, etc.
public class PlatformInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IFacebookService, FacebookService>();
}
}
Then when you load your app you would pass this into the ctor like:
new App(new PlatformInitializer())
Note that there are a couple of different ways to register a service. The one shown above registers the service as a transient so each time it is requested you will get a new instance. You can also call RegisterSingleton or RegisterInstance (if you have already created an instance) to get the same instance across your app

Register generic types in SimpleInjector Version 3

I've been following the very helpful answer here to organise my unit of work and repositories dynamically using SimpleInjector DI.
Using the test service below:
public class TestService
{
public TestService(IRepository<Call> calls){}
}
In the controller:
public class TestingController : Controller
{
private readonly IUnitOfWork _unitOfWork ;
public TestingController(IUnitOfWork unitOfWork, TestService testService)
{
_unitOfWork = unitOfWork;
}
}
And the bootstrapper:
public static class BootStrapper
{
public static void ConfigureWeb(Container container)
{
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Options.ConstructorResolutionBehavior = new GreediestConstructorBehavior();
container.Register<DbContext, OCISContext>(Lifestyle.Scoped);
container.Register<ApplicationUserManager>(Lifestyle.Scoped);
container.Register<ApplicationSignInManager>(Lifestyle.Scoped);
container.Register<IAuthenticationManager>(() =>
AdvancedExtensions.IsVerifying(container)
? new OwinContext(new Dictionary<string, object>()).Authentication
: HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
container.Register<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(Lifestyle.Scoped);
container.Register<IUnitOfWork, UnitOfWork.UnitOfWork>(Lifestyle.Scoped);
container.RegisterCollection(typeof(IRepository<>), typeof(IRepository<>).Assembly);
container.Register<TestService>(Lifestyle.Scoped);
}
I get the error:
An exception of type 'System.InvalidOperationException' occurred in SimpleInjector.dll but was not handled in user code
Additional information: The configuration is invalid. Creating the instance for type TestService failed. The constructor of type TestService contains the parameter with name 'calls' and type IRepository<Call> that is not registered. Please ensure IRepository<Call> is registered, or change the constructor of TestService. There is, however, a registration for IEnumerable<IRepository<Call>>; Did you mean to depend on IEnumerable<IRepository<Call>>?
I've also, tried
container.RegisterCollection<IRepository>(new [] {typeof(IRepository)});
container.RegisterCollection(typeof(IRepository), new[] {typeof(IRepository)});
My intention is to get an instance of GenericRepository as this implents IRepository as shown in the answer in the link above.
The exception message you get is actually pretty clear (or at least, to me):
Please ensure IRepository<Call> is registered, or change the constructor of TestService. There is, however, a registration for IEnumerable<IRepository<Call>>; Did you mean to depend on IEnumerable<IRepository<Call>>?
In other words, you made the following registration:
container.RegisterCollection(typeof(IRepository<>), typeof(IRepository<>).Assembly);
RegisterCollection means that registrations can be resolved as collection. Your TestService however depends on IRepository<Call> instead of IEnumerable<IRepository<Call>>.
Since I think it is unlikely that your application will use multiple implementations for IRepository<Call> at the same time, registration of collections is probably not what you want; there is likely a one-to-one mapping between a closed version of the generic IRepository<T> interface and an implementation.
So instead, make the registration as follows:
container.Register(typeof(IRepository<>), new[] { typeof(IRepository<>).Assembly });
This ensures the one-to-one mapping and will throw an exception in case there accidentally are more implementations for the same closed generic type.

How to resolve UnityContainer and when in windows serivce

I am creating a Windows Service which uses existing class library for application and domain models.
Application layer already have already defined ContainerConfig which registers all Interfaces like
public class ConfigContainer
{
public UnityContainer ContainerConfig()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IAttachmentService, AttachmentService>(new ContainerControlledLifetimeManager());
container.RegisterType<IBrxxgeService, BrxxgeService>(new ContainerControlledLifetimeManager());
container.RegisterType<ICaxxxxociationService, CaxxxxociationService>(new ContainerControlledLifetimeManager());
container.RegisterType<ITraxxxacityService, TraxxxcityService>(new ContainerControlledLifetimeManager());
return container;
}
}
There are more than 30 Service Interfaces registered here like that. in Window Service Program.cs
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new DClearanceService()
};
ServiceBase.Run(ServicesToRun);
}
Then in DClearanceService.cs
public partial class DClearanceService : ServiceBase
{
private ConfigContainer _containerConfig = new ConfigContainer();
private UnityContainer _container = new UnityContainer();
public DimensionalClearanceService()
{
InitializeComponent();
ExceptionHandlingManager.InitializeExceptionManager();
_container = _containerConfig.ContainerConfig();
}
Inside my methods are resolving container:
public class EMTrocessor
{
_clRequestService = Container.Resolve<IClRequestService>();
public bool ProcessMessage(string message)
{
List<ClOutput> clOutputs = _clRequestService.GetClOutputs();
}
}
If I run this code using visual studio in debugger mode, it works fine but when I run this windows service, I get Microsoft.Practices.Unity.ResolutionFailedException
<Description>An exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred and was caught.</Description>
<DateTime>2015-11-30 16:53:55Z</DateTime>
<ExceptionType>Microsoft.Practices.Unity.ResolutionFailedException, Microsoft.Practices.Unity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f</ExceptionType>
<Message>Resolution of the dependency failed, type = "CPR.Apps.Application.Interfaces.IClEventService", name = "(none)".
Exception occurred while: Calling constructor CPR.Apps.Application.Services.CleranceEventService().
Exception is: ResolutionFailedException - Resolution of the dependency failed, type = "CPR.Apps.Domain.Interfaces.IClEventManager", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, CPR.Apps.Domain.Interfaces.IClEventManager, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving CPR.Apps.Domain.Interfaces.IClEventManager,(none)
When I call service, it already resolves the related service and this is how visual studio interact with db and returns the result. Why it can't do the same when I run Windows Service?
My question is:
how do I resolve this issue? Do I need to add
_attachmentService = Container.Resolve<IAttachmentService>();
_brxxgeService = Container.Resolve<IBrxxgeService>();
_clRequestService = Container.Resolve<IClRequestService>();
for all of the interface services here?
if yes, where should I add them?
Please help.
Better way to use continer extensions:
public class ModelContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IAttachmentService, AttachmentService>(new ContainerControlledLifetimeManager());
Container.RegisterType<IBrxxgeService, BrxxgeService>(new ContainerControlledLifetimeManager());
Container.RegisterType<ICaxxxxociationService, CaxxxxociationService>(new ContainerControlledLifetimeManager());
Container.RegisterType<ITraxxxacityService, TraxxxcityService>(new ContainerControlledLifetimeManager());
}
}
public partial class DClearanceService : ServiceBase
{
private UnityContainer _container = new UnityContainer();
public DimensionalClearanceService()
{
InitializeComponent();
ExceptionHandlingManager.InitializeExceptionManager();
_container.AddExtension(new ModelContainerExtension());
}
Why it's better? In your case you replace whole container variable, and if you made some registraions before - you'll lose it. With AddExtension you'll add new registrations to existing ones.

Categories

Resources