I'm creating a project soon to be a nuget. There is a public class where I inject a class whose visibility modifier is internal, but the compiler states:
Inconsistent accessibility: parameter type 'blah' is less accessible than method 'bleh'
I don't want to expose the rest of the project classes to the rest of the world. Is it possible to do?
AuthenticationContext resolution:
You can inject IServiceProvider and get your service like
var authContext = _serviceProvider.GetService<AuthenticationContext>();
or you need to change accessibility of your method
Related
I have an WebApi application using OWIN and Autofac. Although controllers and parameters get resolved correctly, I would like to be able to use OwinContext.Get<type> to resolve types registered with Autofac. Is that posible?
Already setapp.UseAutofacMiddleware(container); and config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
By example, I registered builder.Register<IAppConfiguration>(c => new AppConfig()); and I'd like to resolve it using owinContext.Get<IAppConfiguration>().
There is no way to get OwinContext.Get<T> to resolve things from Autofac. If you dive into Microsoft.Owin.OwinContext.Get in Reflector, you'll see it's backed entirely by a dictionary of things you register with an environment. It's not dynamic and there's no way (without creating your own IOwinContext implementation) to get it to resolve things either out of the dictionary or out of dependency resolution.
If you are in a DelegatingHandler or an ApiController you will have a reference to the current HttpRequestMessage. Use message.GetDependencyScope() to get the current request-level dependency scope to resolve services.
public HttpResponseMessage SomeControllerAction()
{
var service = this.Request.GetDependencyScope().GetService(typeof(Service));
}
If you have access to the HttpConfiguration then you can use the HttpConfiguration.DependencyResolver to resolve things. Note that resolver will not have per-request dependencies available. Web API tracks request dependency scope with the inbound HttpRequestMessage so be aware of that limitation. There is an FAQ about per-request lifetime scope that can help you through that.
If you're in a place where there's only an IOwinContext, you may need to make use of a package like CommonServiceLocator and the associated Autofac.Extras.CommonServiceLocator. There really isn't a way to get a reference to the current HttpConfiguration or global container just from an IOwinContext. Again, if you go this route, you won't have per-request dependencies available, so be aware.
The IOwinContext.Get uses the Environment dictionary, resolving objects registered directly with Owin, it does not take into account Autofac container.
I managed to do it by accessing the Autofac OwinLifetimeScope in the Environment property and using the scope to resolve the service.
You can access the LifetimeScope using this code
var scope=OwinContext.Get<Autofac.Core.Lifetime.LifetimeScope>("autofac:OwinLifetimeScope");
and then
scope.GetService(type)
You should check for nulls and write it in a better way, as Extension method maybe.
If you have WebAPI in your project, you can simulate a http request like this
var dependencyScope = new AutofacWebApiDependencyScope(owinContext.GetAutofacLifetimeScope());
var myService = dependencyScope.GetService(typeof(MyService));
I'm trying to implement a role provider using a separate EF repository class, as an injectable dependency, to access my roles store. My problem is that the role provider is defined in configuration (web.config) and therefore is not instantiated via the Unity DI container. I haven't been able to find a way to either shift the configuration to code or get hold of the role provider after it's built to call container.BuildUP() on it. Any suggestions would be appreciated.
I think that my question's solution is fairly well covered here:
Property injection in custom membership provider using Castle
If I'd searched on MembershipProvider instead of RoleProvider probably would have found it the first time through.
Just to summarize my solution, the link lead me to the Common Service Locator library at codeplex.
It and the Unity adapter for it are included in the Nuget package for Unity 3. So I already had it.
I added one line to the end of the Compose() method of my CompositionRoot class:
var locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
And I can now access the locator/container thru the static ServiceLocator class in the constructor of my RoleProvider:
public IAuthorizationManager Manager {get; set;}
public MyRoleProvider()
{
var locator = ServiceLocator.Current;
Manager = locator.GetInstance<IAuthorizationManager>();
}
(Of course, you need 'using' statements for Microsoft.Practices.ServiceLocation)
I'm working on a WCF service that uses a duplex channel to allow the service to call back to the client to relay an event raised by a component in the service layer. The proxy class is defined and constructed like this:
public class EvsMembershipProxy : DuplexClientBase<IMembershipProviderCallback>, IEvsMembershipProvider
{
public EvsMembershipProxy(InstanceContext callbackInstance): base(callbackInstance)
{
}
}
I need to get an instance of this class in a class that is configured using the ASP.NET membership system, so I bind it like this:
_ninjectKernal.Bind<IEvsMembershipProvider>().To<EvsMembershipProxy>();
and I inject it like this:
public class EvsMembershipProvider : MembershipProvider, IMembershipProviderCallback
{
#region "Dependencies"
[Inject]
public IEvsMembershipProvider MembershipProvider { get; set; }
#endregion
}
The configured membership provider is injected by Ninject like this:
_ninjectKernal.Inject(System.Web.Security.Membership.Provider);
_ninjectKernal.Inject(System.Web.Security.Roles.Provider);
I have tested the injection pattern with the WCF service layer without the duplex service and it works correctly. However, when I include the duplex service, Ninject fails during binding with the following error:
Error activating ServiceHostBase
No matching bindings are available, and the type is not self-bindable.
Activation path:
4) Injection of dependency ServiceHostBase into parameter host of constructor of type InstanceContext
3) Injection of dependency InstanceContext into parameter callbackInstance of constructor of type EvsMembershipProxy
2) Injection of dependency IEvsMembershipProvider into property MembershipProvider of type EvsMembershipProvider
1) Request for EvsMembershipProvider
Suggestions:
1) Ensure that you have defined a binding for ServiceHostBase.
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.
So it looks as though I will need a binding for the ServiceHostBase class used in the EvsMembershipProxy constructor to resolve this issue. However, I don't know how to configure it. My best attempt to resolve the ServiceHostBase binding so far has been:
_ninjectKernal.Bind<ServiceHostBase>().ToMethod(c => OperationContext.Current.Host);
However this fails with a null reference exception during binding.
How do I bind the ServiceHostBase type so that this injection works?
** EDIT: simplified the original code to remove some of the EvsMembershipProxy constructor arguments which could be supplied by WCF configuration **
Discovered I could configure it like this.
_ninjectKernal.Bind<IEvsMembershipProvider>()
.To<EvsMembershipProxy()
.WithConstructorArgument("callbackInstance", Membership.Provider);
The configured membership provider implements the IMembershipProviderCallback interface and receives the callback from the service.
I am building a WPF based application. I am using Unity to inject all the different dependencies in my application (defined in App.xaml.cs).
In my MainApplication window I have a pretty complex look-less custom control derived from Control(is has about ten more control integrated in it).
I would like to inject a VM into this custom control without coupling it to any other object in my application (except App.xaml.cs of course)
Injection to any WPF window in my application works well, but when I try injecting to the custom control I am facing to different situation:
1. In case I am using
container.RegisterInstance(container.Resolve);
The DI creates a dummy instance of MyCustomControl and injects the VM (using [Dependency] attribute). However this specific instance is not used when I use it in my XAML:
in which case it initializes a new MyCustomControl ignoring any dependencies.
In case I am using
container.RegisterType();
The MyCustomControl completely ignores the injection.
I realize I am probably doing something wrong (not just technically) and I am really trying to avoid coupling this control (which will obviously solve the issue).
I don't know if this is the best solution and found your question while looking for other options but, alas, here is the approach I used to at least get up and running.
I created a base UnityControl class that subclasses Control. In the constructor, I use the ServiceLocator to get a reference to the container. Then I call the BuildUp method to resolve any dependencies on the derived control class. Any dependencies are implemented as read/write properties marked with the DependencyAttribute.
Here's what UnityControl looks like:
public abstract class UnityControl : Control
{
protected UnityControl() : base()
{
Container = ServiceLocator.Current.GetInstance<IUnityContainer>();
Container.BuildUp(this.GetType(), this);
}
protected IUnityContainer Container { get; private set; }
}
I want to use Ninject in my Windows application and I want to know if there is best practices that I can do; strategies to find a balance between performance and maintenance.
The problem with Windows application and Web application is that in Web application, there is a scope easy to define that is the context but with Windows application, you have no scope that is easy to use form after form.
As example, I have a service that query the database. This service have a constructor and received a UnitOfWork. With Ninject, I can create a property marked as to be injected but if I do that, each time I will create this service, a new connection will be created to the database.
Just for this reason, I must manually create my services to control the number of connection created and no dependency injector can be used.
I have found that you can call the Inject method after created the service for inject dependencies but I'm sure I can use a better strategy.
With Ninject, you can have Ninject scope lifetimes of your injected dependencies to any object you want to provide (not just Singleton, Request, Thread, and Transient scopes).
From the Ninject Documentation Wiki:
You can also easily define you own
scopes using the .InScope(object o)
method.
You'll find some actual detail about how object scoping works in this Ninject Google Groups question & answer.
I finally found what I searching for.
Create a class that inherits from 'Ninject.Activation.Provider(of T)'
Overrrides the function 'CreateInstance'
Bind your interface with that 'Bind(Of [Your interface]).ToProvider([Your provider class])'
And now, you will be able to control each instance created that are associated with the specified interface.
Note that you can pass a type or an instance to the provider parameter of the Bind method. You can with an instance create a provider before binding your interfaces and use this provider in your code when you want to create a new instance.
The provider in conjunction with InScope allows great flexibility for each place where you want to have and instance of an object that can be injected automatically and have a determined scope.
Here is an example:
Public Interface IConnection
End Interface
Public Class Connection
Implements IConnection
End Class
Imports Ninject
Public Class StandardModule
Inherits Ninject.Modules.NinjectModule
Public Property ConnectionProvider As ConnectionProvider
Public Overrides Sub Load()
Bind(Of IConnection).ToProvider(Me.ConnectionProvider)
End Sub
End Class
Public Class ConnectionProvider
Inherits Ninject.Activation.Provider(Of IConnection)
Public Property Connection As IConnection
Protected Overrides Function CreateInstance(ByVal context As Ninject.Activation.IContext) As IConnection
Return Me.Connection
End Function
End Class
Imports Ninject
Module EntryPoint
Sub Main()
Dim provider As New ConnectionProvider
Dim standardModule As New StandardModule
Dim connection As IConnection
Dim kernel As New Ninject.StandardKernel()
standardModule.ConnectionProvider = provider
kernel = New Ninject.StandardKernel(standardModule)
' Here you should use a factory instead of create an instance directly but
' for demonstration, it show how an instance can be propagated to object created
' by NInject.
provider.Connection = New Connection
connection = kernel.Get(Of IConnection)()
End Sub
End Module
This article by Ayende in MSDN Magazine is ostensibly about NHibernate, and mentions the word inject only once (and that only wrt AOP), but the phrasing of your question suggests to me it'll be great food for thought as you consider how to architect your app.
You can also make your frameworks depend on a factory instance, and rely on the factory to perform your connection pooling.
Alternatively, you can use Ninject itself to always use the same object instance for the particular type.