How to get current IUnityContainer to register more types - unity-container

I have a windows service that is using Microsoft's Unity 2.1, typically all the types are registered during the service startup. (program.cs)
There is also a Windows Service Class. I need to get access to current IUnityContainer in this service class to register a type.
How do i get access to IUnityContainer so that i can register more types?

There is no concept of Current IUnityContainer as you can have multiple of these, even though this is a very rare thing, in my experience, if you don't count the child containers. There are however multiple ways you can keep a hold on your container though. You can do what's suggested in this answer, by doing that at a higher level, but I'd recommend against it. What I've taken a habit of doing is:
In the non-main projects, I create a static class such as:
static class UnityRegistrator
{
public static void Register(IUnityContainer container)
{
// Whatever Registrations for types in this assembly.
container.RegisterType<INamedClass, ClassLibrary2>(
new InjectionConstructor(
new ResolvedParameter<string>("Foo")));
}
}
And in the main project, for example in your program.cs:
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
MyAssembly.UnityRegistrator.Register(container);
var namedClass = container.Resolve<INamedClass>();
namedClass.Whatever();
}
static void Register(IUnityContainer container)
{
// Whatever Registrations for types in this assembly.
container.RegisterType<string>("Foo", "Bar");
}
}

Related

How do you inject a view dependency into Presenter (MVP) in ASP.NET Web Forms using Simple Injector or Microsoft.Extensions.Dependency?

The following example shows a scenario where I'm trying to implement a DI container. In this case, I'm trying to use Simple Injector or Microsoft.Extensions.DependencyInjection DI Container. I've seen code examples that start hitting around the target, such as here, but no bullseye as of yet.
Below is a general code sample that I would like to modify to use one of the aforementioned DI containers (Used Simple Injector for example). I could move the view out of the presenter constructor and set it as a property. However, I was hoping for a more eloquent solution also it is a dependency that needs to be injected.
I know .NET 4.7.2 has increased DI support functionality but the biggest benefit seems to be allowing dependencies to be easily injected into pages/user controls. For MVP architecture I need the concrete class of the page tied to its view interface so the DI container can resolve and pass into the presenter, as the presenter depends on the view. I've not seen an example of this implemented well other than Unity using its DependencyOverride, which can pass the concrete class at runtime.
public partial class UserLoginView : IUserLoginView
{
private UserLoginPresenter _userLoginPresenter;
protected override void OnLoad(EventArgs e)
{
//This is my problem:
//An error will be thrown "...contains the parameter with name
//'view' and type IUserLoginView, but IUserLoginView is not
//registered..."
_userLoginPresenter = SimpleInjectorDependencyInjector
.GetInstance<IDeveloperTestStatusPresenter>();
}
}
public class UserLoginPresenter : IUserLoginPresenter
{
private readonly IUserLoginView view;
private readonly IUserService _userService;
public UserLoginPresenter(IUserLoginView userLoginView,
IUserService userService)
{
this.view = userLoginView;
this._userService = userService;
}
public static class SimpleInjectorDependencyInjector
{
private static readonly Container container = new Container();
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
//Assume this is called from App on start
public static void RegisterClasses()
{
container
.Register<IUserLoginPresenter, UserLoginPresenter>();
container
.Register<IUserService, UserService>();
}
}
I was able to accomplish what I was looking for using Microsoft.Extensions.DependencyInjection Container.
In my MSDependencyInjector wrapper class, I used the ActivatorUtilities extension.
public static T GetService<T, I>(I interfaceInstance)
{
return ActivatorUtilities.CreateInstance<T>(container, interfaceInstance);
}
Implemented in my page's partial class I wrote:
_userLoginPresenter = MSDependencyInjector.GetService<UserLoginPresenter,
IUserLoginView>(this);
A Caveat: The 'T' parameter of createInstance wants the concrete class type not the interface. This caused hours of frustration, prompting the creation of this question in the first place. MS documentation isn't the greatest but I definitely misread.
I'm not sure how to implement something as straightforward in Simple Injector and would be interested in knowing. Based on my reading I not sure if my solution isn't something like a service locator, which depending on which camp you are from should be avoided. However, if the implementation of this can be contained for just solving the need for this MVP paradigm then it is my hope all will be well.

how to get HttpContext.Current.GetOwinContext() in startup

I very read for this problem but i can not fixed this so i think create a new question in this site.
HttpContext.Current.GetOwinContext();
i want get GetOwinContext values with above code . above code there are in my startup.cs
[assembly: OwinStartupAttribute(typeof(OwinTest.Startup))]
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var c = HttpContext.Current.GetOwinContext();
}
}
and i get this error
//No owin.Environment item was found in the context
but var c = HttpContext.Current.GetOwinContext(); work for me in HomeController fine.!
I just get GetOwinContext in my startup.cs class.
thankfull
You can't do that. The OWIN context does not exist without a request, and the Startup class only runs once for the application, not for each request. Your Startup class should initialize your middleware and your application and the middleware and the application should access the OWIN context when needed.
As mentioned, what you are asking isn't possible. However, depending on your requirements, the following is possible and gives you access within the context of creating object instances. This is something I needed in order to check for whether an instance was already added else where (I have multiple startup classes in different projects).
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
// Ensure we have our "main" access setup
app.CreatePerOwinContext<DataAccessor>(
(options, owinContext) =>
{
// Check that an instance hasn't already been added to
// the OwinContext in another plugin
return owinContext.Get<DataAccessor>() ?? DataAccessor.CreateInstance(options, owinContext);
}
);
}
Within the CreatePerOwinContext we have access to the OwinContext, so we can access it at the point of creating a new type. This might not help everyone as it's a little more specific to a person's needs, but is useful to know.

Referencing in the context of asp.net Identity 2.0 separation

I try to separate one of my API projects into three different layers.
The API
Data access(repos + uow)
Data Entities
The API is using Asp.net Identity 2.0 with code from a sample I installed, just enough to work with OAuth Authorization.
However, When I do this separation, sometimes I get an error telling me that I need to reference the third layer(entities) from my first layer. And I can't figure out why. That would break the whole purpose of the separation, right?
For example, when I try to replace this line(from the API layer in Startup.Auth.cs, ConfigureAuth method)
app.CreatePerOwinContext(ApplicationDbContext.Create);
With
app.CreatePerOwinContext(uow.CreateDbContext())
A method that returns a new instance of the ApplicationDbContext.
I would expect that context to be returned from my second layer, where my UnitOfWork is(which in turn gets the ApplicationDbContext from the data layer).
Could someone please explain how this works?
To solve your issue you need to start use Interfaces and any DI-framework. Here I can provide you with the code if you want to start using AutoFac (https://code.google.com/p/autofac/wiki/WebApiIntegration).
When you installed AutoFac to your solution through Nuget. Add this part of code in your Global.asax.cs file.
protected void Application_Start()
{
...
SetupAutoFac();
...
}
private static void SetupAutoFac()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
var container = builder.Setup();
var resolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
Create this part of code in your BLL-layer:
public static class AutoFacConfiguration
{
public static IContainer Setup(this ContainerBuilder builder)
{
REGISTER ALL YOUR SERVICES AND UOW HERE
return builder.Build();
}
}
After this you can inject every services Interface to your ApiControllers, and the the WebAPi will only have a reference to your BLL-layer or to the layer where you put all your interfaces.

Using an existing IoC Container in SignalR 2.0

How can I use an existing IoC with SignalR 2.0?
From the tutorial, it seems I need to setup a class to be called from OWIN via an attribute:
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
public class Startup
{
public void Configuration(IAppBuilder app /*HOW AM I GONNA GET UNITY CONTAINER HERE?*/)
{
var hubConfig = new HubConfiguration()
{
EnableJSONP = true,
EnableDetailedErrors = true,
EnableJavaScriptProxies = true,
Resolver = new SignalRUnityDependencyResolver(container)
};
// Any connection or hub wire up and configuration should go here
app.MapSignalR(hubConfig);
}
}
}
The problem here is that I already have a container, that's boot strapped and there are singleton instances in the container that needs to be shared with the MVC app shared under the same host.
However the trouble here is that unlike before, it doesn't look like I can call the MapSignalR method from my own code. Rather I need to rely on OWIN to do this for me. However OWIN is not aware of the container that I already setup.
What's the best way to resolve this? I have some very crude ideas how to hack a solution together using static variables to hold some of these - but I hate the very thought of it. The code will be brittle and order of operation could easily introduce a subtle bug.
Is there a way to get a hold of the IAppBuilder instance without having OWIN invoke the above method? This way I can control better when SignalR gets initialized and I can pass my own IoC into the configuration.
In my case I have created a custom hub activator which uses a shared container between my app and signalR (by constructor injection) that way you´ll have single composite root for the whole application.
try the following:
public class CustomHubActivator : IHubActivator
{
private readonly Container _container;
public MseHubActivator(Container container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return _container.GetInstance(descriptor.HubType) as IHub;
}
}
register your custom hub activator when you´re bootstrapping your app (maybe the global.asax)
GlobalHost.DependencyResolver.Register(typeof (IHubActivator),
() => new CustomHubActivator(Container));
that´s much simplier solution rather than to configure again the signalR dependencyResolver

Autofac, ASP.NET and Microsoft.Practices.ServiceLocation

I've been working thru the details of implementing IoC in my web apps but in a way that leverages Microsoft.Practices.ServiceLocation. I am specifically using Autofac and the asp.net integration, but I wanted to leave myself open to other containers. Along the lines of this question, i was concerned about how to access the container in my web app code.
I have a 'core' library that primarily defines interfaces to be resolved. This core library is used by my web app and other apps as well. Very handy to have common interfaces defined. I thought this was an excellent place to put access to the IoC container, and I did so with a static class. The trick is injecting the container into the static class.
It's tricky in a web environment becuase the container may be different for each request, while in a non-web app it will probably be the same all the time. At first I tried injecting the container direclty with a method but that quickly failed on the next web request! So I came up with this:
public static class IoCContainer
{
public static void SetServiceLocator(Func<IServiceLocator> getLocator)
{
m_GetLocator = getLocator;
}
static private Func<IServiceLocator> m_GetLocator = null;
public static T GetInstance<T>(string typeName)
{
return m_GetLocator().GetInstance<T>(typeName);
}
}
Now in my global.asax.cs I do this:
protected void Application_Start(object sender, EventArgs e)
{
var builder = new Autofac.Builder.ContainerBuilder();
... register stuff ...
var container = builder.Build();
_containerProvider = new Autofac.Integration.Web.ContainerProvider(container);
Xyz.Core.IoCContainer.SetServiceLocator(() =>
new AutofacContrib.CommonServiceLocator.AutofacServiceLocator
(_containerProvider.RequestContainer));
}
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
static IContainerProvider _containerProvider;
And calls to resolve dependences look like
var someService = Xyz.Core.GetInstance<ISomeService>();
So rather than pass a specific container I pass a delegate that knows how to GET a container. For non-web applications the delegate would probably just return what builder.Build() serves up.
My question to the experts is, does this make sense? I have an easy way to get to something that can resolve dependencies without knowing what the container product is or where the container itself comes from. What do you think?
We use a similar pattern mostly due to the fact that IoC was introduced into a non-DI architecture. Thus the need to be able to explicitly call the container to get services, which basically is the Factory pattern.
The true benefit of IoC is achieved when all dependencies can be injected and your code no longer have a dependency on the service locator. Autofac.Integration.Web have handlers that will perform injection into your page objects which will make the static service locator obsolete. Imo this is the preferred way, though (as in our case also) service locator cannot always be avoided.
That said, since you already have isolated your app from the container using IoCContainer class, I see no reason to have the additional abstraction of AutofacServiceLocator within IoCContainer. Bottom line is that IoCContainer is already your service locator and should be "allowed" direct access to the container implementation.
Here is my take on your service locator class:
public static class IoCContainer
{
private static IContext GetContainer()
{
var cpa =
(IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
return cpa.ContainerProvider.RequestContainer;
}
public static T GetInstance<T>()
{
return GetContainer().Resolve<T>();
}
}

Resources