My current implementation of some ASP.NET web application registers all repository classes and some helper service classes in my wrapper around unity container:
public class MyUnityContainer : UnityContainer
{
public MyUnityContainer ()
{
string strConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
_context = new MyDataClassesDataContext(strConnectionString);
this
.RegisterInstance(typeof(CMCoreDataClassesDataContext), _context, new ContainerControlledLifetimeManager())
;
// Register Repository classes
this
.RegisterType<IBlockedRegistrationRepository, BlockedRegistrationRepository>()
.RegisterType<ICmOptionRepository, CmOptionRepository>()
.RegisterType<ICommandExecutionLogRepository, CommandExecutionLogRepository>()
...
}
public static T GetContainer<T>(IDictionary items) where T : class, IUnityContainer, new()
{
T container;
lock (Lock)
{
if (items.Contains(UnityKey) == false)
{
container = new T();
items.Add(UnityKey, container);
}
else
{
container = items[UnityKey] as T;
}
}
return container;
}
Here is an example how container is instantiated (I create a new instance of the container per each request, but only one instance per request):
using (IUnityContainer container = MyUnityContainer.GetContainer<McaUnityContainer>(HttpContext.Current.Items))
{ ... }
Everything is working fine, but what one thing is confusing me a lot: now I have almost 50 classes been registered each time when container is created. Not all classes are actually used for each request...
Is not it a performance overhead to ALWAYS register everything in container?
Probably I shouldn't instantiate a new container instance for each request (and use something like containers pool)?
What is a best practice recommendations for this case?
Thanks a lot.
Any thoughts are welcome!
In our internal framework, we have a static instance of the Unity container that hangs off the Global.asax file, and gets instantiated (and filled with registrations) on Application Start.
On each request, we use Container.CreateChildContainer() to get a request-specific container that gets a very few request-specific registrations (even fewer if you use Unity 2.0 with HierarchicalLifetimeManager). The request-specific container is what gets used during the request.
Edited to add: Not to say this is necessarily a best practice. It certainly avoids any registration overhead though, except for app startup where I have bigger fish to fry from an overhead perspective.
I register everything needed by the web application in Application_Start. I have a RequestLifetimeManager like this and a SessionLifeTimeManager, to make request-specific and session-specific dependencies to be created only when needed: didn't yet see performance or memory issues related to this approach. Our policy is to create a child container when the context is different, for instance in web services or background tasks.
Related
I'm trying to implement the Identity system in an ASP.NET Core app (RC2 libraries) and there is a particular hangup that is driving me crazy.
First of all, I am not using EntityFramework. I'm not even using SQL. I'm backing up to RavenDB, so I need the implementation to be very specific to that; Which isn't a problem.
So I designed a RavenUserStore class, and it looks like this;
public class RavenUserStore<TUser> :
IUserStore<TUser>,
IUserLoginStore<TUser>,
IUserPasswordStore<TUser>,
IUserRoleStore<TUser>,
IUserSecurityStampStore<TUser>,
IUserClaimStore<TUser>,
IUserLockoutStore<TUser>,
IUserTwoFactorStore<TUser>,
IUserEmailStore<TUser> {
// ...
}
Works great on its own. I've implemented all the methods, etc. It's wonderful. Very clean and efficient.
Now, I go over to my web application and wire things up;
services.AddTransient<ILookupNormalizer>(s => new LowerInvariantLookupNormalizer());
services.AddTransient<IPasswordHasher<Member>>(s => new PasswordHasher<Member>());
services.AddTransient<IUserStore<Member>, RavenUserStore<Member>>();
services.AddIdentity<Member, Role>(o => {
o.Password.RequiredLength = 6;
o.Password.RequireDigit = true;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
})
.AddUserStore<RavenUserStore<Member>>()
.AddRoleStore<RavenRoleStore<Role>>();
So I go make a controller to use this, per all the samples I've seen, and the very core sample from the Identity Framework Github Repository
//... [PROPERTIES]...//
public AccountController(UserManager<Member> userManager, SignInManager<Member> signInManager) {
// ... [attach constructor parameters to properties] ...//
}
Alright, so I inspect the classes carefully.
UserManager<T> has a property Store,which is a type of IUserStore<T>.
So theoretically.. if the dependency injection resolves types of IUserStore<T> to RavenUserStore<T> when they are injected through a constructor.. shouldn't that mean that the UserManager<T> gets a RavenUserStore<T> as its Store property?
I thought it would too; But when I call methods on the UserManager, it DOES NOT call the ones on my RavenUserStore. Why is this? What can I do?
Do I really have to ALSO make a custom UserManager class and do all of those methods AGAIN?
You need to add your own custom providers before calling services.AddIdentity(). Internally, AddIdentity uses TryAddScoped() which only adds the default items if they don't already exist in the services container.
So just putting the call to AddIdentity() after you registered all your custom implementations should mean that they will take precedence as you expect.
Can we use Unity interception/extensions/custom proxy to perform this?
// psuedo-code
using (var childContainer = new container.CreateChildContainer())
using (var scope = new TransactionScope())
{
childContainer.Resolve<TMyService>().PerformCall(...);
scope.Complete();
}
Currently the above code is implemented as a WCF behaviour. We now have classes that access this service layer directly rather then making WCF calls and need this behaviour. The interesting part is we need to create a child container inside the unity interception.
Yes. I don't see why you couldn't. However...
although the use of interception often loosens the need to have a clean and SOLID design, when you want to do this, you still need a SOLID design.
I've written about these kind of designs that enable this here, and what it comes down to is that you will have model the operations you want to wrap behind a design, such as an ICommandHandler<T> with a Handle(T) method. With such a design, you can create a decorator (or in Unity's case an interceptor) that wraps a real class with a class that adds a child container like this:
public class ChildContainerCommandHandlerDecorator<T>
: ICommandHandler<T>
{
private readonly ICommandHandler<T> decorated;
private readonly Container container;
public ChildContainerCommandHandlerDecorator(
ICommandHandler<T> decorated, Container container)
{
this.decorated = decorated;
this.container = container;
}
public void Handle(T command)
{
using (container.CreateChildContainer())
{
this.decorated.Handle(command);
}
}
}
And a decorator that adds a transaction scope like this:
public class TransactionCommandHandlerDecorator<T>
: ICommandHandler<T>
{
private readonly ICommandHandler<T> decorated;
public TransactionCommandHandlerDecorator(
ICommandHandler<T> decorated)
{
this.decorated = decorated;
}
public void Handle(T command)
{
using (var scope = new TransactionScope())
{
this.decorated.Handle(command);
scope.Complete();
}
}
}
By wrapping real handlers in both decorators, you can extend handlers with this behavior. Of course, decorators is a concept that Unity is unable to handle, but you can easily rewrite this using interceptors when working with Unity, but again, good design is your only friend here.
No, I don't see a way you could do this. You could do the TransactionScope part, but the resolve/call part I just don't see working.
Well, I guess you could get it to work. You'd need a dummy instance of TMyService (or whatever object you're intercepting), and your interception behavior would need to do a bunch of reflection to figure out the type to grab, resolve it, and use reflection again to invoke the specific method. It could be done, but it would be hideously slow.
I'm not going to provide code for this, because I don't think it's a good idea. What scenario are you trying to implement with this - there's probably an easier way to accomplish it.
I'm in the middle of a significant effort to introduce NHibernate into our code base. I figured I would have to use some kind of a DI container, so I can inject dependencies into the entities I load from the database. I chose Unity as that container.
I'm considering using Unity's interception mechanism to add a transaction aspect to my code, so I can do e.g. the following:
class SomeService
{
[Transaction]
public void DoSomething(CustomerId id)
{
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
}
}
and the [Transaction] handler will take care of creating a session and a transaction, committing the transaction (or rolling back on exception), etc.
I'm concerned that using this kind of interception will bind me to using Unity pretty much everywhere in the code. If I introduce aspects in this manner, then I must never, ever call new SomeService(), or I will get a service that doesn't have transactions. While this is acceptable in production code, it seems too much overhead in tests. For example, I would have to convert this:
void TestMethod()
{
MockDependency dependency = new MockDependency();
dependency.SetupForTest();
var service = SomeService(dependency);
service.DoSomething();
}
into this:
void TestMethod()
{
unityContainer.RegisterType<MockDependency>();
unityContainer.RegisterType<IDependency, MockDependency>();
MockDependency dependency = unityContainer.Resolve<MockDependency>();
dependency.SetupForTest();
var service = unityContainer.Resolve<SomeService>();
service.DoSomething();
}
This adds 2 lines for each mock object that I'm using, which leads to quite a bit of code (our tests use a lot of stateful mocks, so it is not uncommon for a test class to have 5-8 mock objects, and sometimes more.)
I don't think standalone injection would help here: I have to set up injection for every class that I use in the tests, because it's possible for aspects to be added to a class after the test is written.
Now, if I drop the use of interception I'll end up with:
class SomeService
{
public void DoSomething(CustomerId id)
{
Transaction.Run(
() => {
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
});
}
}
which is admittedly not as nice, but doesn't seem that bad either.
I can even set up my own poor man's interception:
class SomeService
{
[Transaction]
public void DoSomething(CustomerId id)
{
Interceptor.Intercept(
MethodInfo.GetCurrentMethod(),
() => {
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
});
}
}
and then my interceptor can process the attributes for the class, but I can still instantiate the class using new and not worry about losing functionality.
Is there a better way of using Unity interception, that doesn't force me to always use it for instantiating my objects?
If you want to use AOP but are concerned abut Unity then I would recommend you check out PostSharp. That implements AOP as a post-compile check but has no changes on how you use the code at runtime.
http://www.sharpcrafters.com/
They have a free community edition that has a good feature set, as well as professional and enterprise versions that have significantly enhanced feature sets.
My goal is to have one data context (MainDbContext) per HTTP request in ASP.NET MVC and dispose the data context when the request ends.
I'm using the following StructureMap configuration:
public static class ContainerConfigurer
{
public static void Configure()
{
ObjectFactory.Initialize(x =>
{
x.For<MainDbContext>().HttpContextScoped();
});
}
}
Whenever I need a MainDbContext, I'm using this code:
var dbContext = ObjectFactory.GetInstance<MainDbContext>();
This is working as expected: only one data context is being created per HTTP request. The problem is, MainDbContext is not being disposed at the end of the request.
How can I configure my ObjectFactory to dispose the data context when the HTTP request finishes? Or is this just something I need to do manually using Application_EndRequest() in Global.asax.
Update
I just tried adding the following code to Global.asax:
protected virtual void Application_EndRequest()
{
ObjectFactory.GetInstance<MainDbContext>().Dispose();
}
As expected, this solves the problem. I'm still wondering if there's any way to do this automatically with StructureMap, however.
Instead of:
x.For<MainDbContext>().HttpContextScoped();
Try:
x.For<MainDbContext>().HttpContextScoped().Use(() => new MainDbContext());
Also normally it's repository classes that need a db context. So instead of ObjectFactory.GetInstance<MainDbContext>(); have your repositories take some interface db context and configure StructureMap to inject the MainDbContext into them. Then make StructureMap inject repositories into controllers, ...
In Application_EndRequest:
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
Using a nested container is the only way to get Structure Map to automatically dispose objects. If you're not using that technique the only way is to dispose the objects yourself using either the way the OP described (pulling the object from the container and disposing it; see this NHibernate example for one way to do it) or to scope the object to HttpRequest and call ReleaseAndDisposeAllHttpScopedObjects as Darin described.
I want to implement IOC in my application but i am confused, in my application i have multiple concrete classes which implement an interface. Consider this scenario:-
I have an Inteface ICommand and following concrete types which implement this interface:-
AddAddress
AddContact
RemoveAddress
RemoveContact
Basically user performs all this action in UI and then List is passed to the service layer where each command is executed.
So in GUI layer I will write
ICommand command1 = new AddAddress();
ICommand command2 = new RemoveContact();
In command manger
List<ICommand> listOfCommands = List<ICommand>();
listOfCommands.Add(command1);
listOfCommands.Add(command2);
Then finally will pass listOfCommands to service layer.
Now as per my understanding of IOC is only one concrete class is mapped to the interface. And we use this syntax to get our concrete type from StructureMap container.
ICommand command = ObjectFactory.GetInstance<ICommand>();
How should i implement IOC in this scenario?
In this scenario you're better off making your commands into value objects, i.e. not created by the IoC container:
class AddAddressCommand {
public AddAddressCommand(string address) {
Address = address;
}
public string Address { get; private set; }
}
When you create a command, you really do want a specific implementation, and you want to parameterise it precisely, both concerns that will work against the services of the IoC container. This will become even more relevant if you decide at some point to serialize the command objects.
Instead, make the service-layer components that execute the commands into IoC-provided components:
class AddAddressHandler : IHandler<AddAddressCommand> {
public AddAddressHandler(ISomeDependency someDependency) { ... }
public void Handle(AddAddressCommand command) {
// Execution logic using dependencies goes here
}
}
In your case, the component that accepts the list of commands to execute will need to resolve the appropriate handler for each command and dispatch the command object to it.
There's some discussion of how to do this with Windsor here: http://devlicious.com/blogs/krzysztof_kozmic/archive/2010/03/11/advanced-castle-windsor-generic-typed-factories-auto-release-and-more.aspx - the community supporting your IoC container of choice will be able to help you with its configuration.
As mentioned by Mark, StructureMap will allow you to set up and call named instances of an interface:
ObjectFactory.Initialize(x =>
{
x.For<ISomeInterface>().Add<SomeImplementation>().Named("SomeName");
}
You can still add a default instance for that particular interface, of course:
ObjectFactory.Initialize(x =>
{
x.For<ISomeInterface>().Add<DefaultImplementation>();
x.For<ISomeInterface>().Add<SomeImplementation>().Named("SomeName");
}
When you call ObjectFactory.GetInstance<ISomeInterface>(); the default instance (the one initialized with Use instead of Add) is the one that will be returned.
So in your case, the set up would look something like:
ObjectFactory.Initialize(x =>
{
// names are arbitrary
x.For<ICommand>().Add<AddAddress>().Named("AddAddress");
x.For<ICommand>().Add<RemoveContact>().Named("RemoveContact");
}
These would be called as pointed out by Mark:
ObjectFactory.GetNamedInstance<ICommand>("AddAddress");
ObjectFactory.GetNamedInstance<ICommand>("RemoveContact");
Hope this helps.
Most IOC containers allow you to register "named instances" of interfaces, allowing you to register several implementations of ICommand, each with its own unique name. In StructureMap, you request them like this:
ObjectFactory.GetNamedInstance<ICommand>("AddAddress");
Have a look at this question to see how you setup the container in StructureMap.