I am making a rest service using ServiceStack (http://www.servicestack.net). I'm using the unit of work pattern for my data access layer. I am using StructureMap to connect all my services and the unit of work together.
What I need to do is to create a single unit of work for each individual request that I receive and then dispose of it after.
I have a WCF Service which is using the mechanism here, http://andreasohlund.net/2009/04/27/unitofwork-in-wcf-using-structuremap.
Essentially resulting in something like this
ObjectFactory.Initialize(x =>
{
x.Scan(a =>
{
a.AssemblyContainingType<IUnitOfWork>();
a.WithDefaultConventions();
});
x.For<IUnitOfWork>().LifeCycleIs(new WcfOperationLifecycle());
}
I am looking for a similar 'Lifecycle' for ServiceStack.
[Solution]
The solution is in the comments of the accepted answer.
a) Set the StructureMap lifecycle to HttpContext
x.For<IUnitOfWork>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.HttpContext));
b) Updated the structure map IOC adapter to extend the IRelease interface
class StructureMapContainerAdapter : IContainerAdapter, IRelease
{
public T Resolve<T>()
{
return ObjectFactory.GetInstance<T>();
}
public T TryResolve<T>()
{
return ObjectFactory.TryGetInstance<T>();
}
public void Release(object instance)
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
}
Sounds like you just want Request Scope?
Also check out the concrete Service base class on how you can use Lazy loading + Dispose() to get this behaviour.
As well as in ServiceStack's new API you can override your services OnBeforeExecute() OnAfterExecute() event hooks by using your own ServiceRunner (in the older API you would need to provide a custom service base class).
Related
Say I've a MVC Core Controller like this:
public class SomeController
{
public SomeController(IConfiguration appConfig, Func<string> someDelegate)
{
}
}
Also, I'm using AutoFac to resolve injections. Object injections are working flawlessly while adding a delegate injection produces an ASP.NET Core exception which tells that Func<string> can't be injected because there's no component to inject with such type.
When I try to manually resolve SomeController using AutoFac I get the desired behavior.
Is there any way to support this scenario without using AutoFac to resolve controllers?
Controllers are not resolved via DI by default, they are constructed in the DefaultControllerFactory or so.
Update
Microsoft.Extensions.DependencyInjection doesn't support named components, discovery, auto registrations, decorators etc.
It's meant to be simple out of the box IoC and provide the base for DI for basic applications and offer easy way for 3rd party IoC containers (with advanced features such as auto discovery, decorators etc.) to be integrated (basically all they need is process the information in IServiceCollection and return their own implementation of IServiceProvider from Configure method).
Tag helpers, controllers and view components are different in this aspect as they have their own activators (the default one use activation utilities, which at some point further down the pipeline use the service provider). For that reasons AddControllersAsServices exists, because it replaces DefaultControllerActivator (which uses ActivationUtilities, see DefaultControllerActivator.cs) with ServiceBasedActivator (which uses IServiceProvider, see ServiceBasedControllerActivator).
Also see this related answer for details on how to resolve controllers, tag helpers and view components via DI.
var builder = services
.AddMvc()
.AddControllersAsServices() // this one for your case
.AddViewComponentsAsServices()
.AddTagHelpersAsServices();
I was just run into this issue myself so I thought I would share for future reference as I had one case where I wanted to resolve a delegate but including an additional library seemed like overkill.
Given the following defintions:
public interface ISomething { /*...*/ };
public interface ISomeService { /*...*/ }
public class SomeService : ISomeService { /*...*/ }
public class Something
{
public Something(ISomeService service, string key) { /*...*/ }
}
// I prefer using a delegate for readability but you
// don't have to use one
public delegate ISomething CreateSomething(string key);
The delegate can be registered like this:
var builder = services
.AddSingleton<ISomeService, SomeService>()
.AddTrasient<CreateSomething>(provider => key => new Something(provider.GetRequiredService<ISomeService>(), key));
I've taken this approach to injecting a custom resource provider in my ASP.NET MVC application, but I'm having some problems with object lifetime management.
I'm using Castle Windsor, so I have the following implementation of the factory:
public class DefaultResourceProviderFactory : ResourceProviderFactory
{
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
// IoC is a static helper class that gives me static access to the
// container. IoC.Resolve<T>(args...) simply calls container.Resolve<T>(args...).
return IoC.Resolve<IResourceProvider>(new { resourceType = "Global" });
}
public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
{
// resourceType
return IoC.Resolve<IResourceProvider>(new { ResourceType = virtualPath });
}
}
However, the IResourceProvider I have registered in the container doesn't seem to have its lifetime managed correctly. It has some other dependencies of its own, some of which have somewhat complicated lifestyles (per web request or per transaction), so I've registered the IResourceProvider as transient to ensure that its dependencies are always valid. But the MVC framework is stepping on my toes, keeping a reference to the IResourceProvider across web requests, which causes ObjectDisposedExceptions when its dependencies have been invalidated on the next request.
What I'd like to do, is to make the MVC framework use the factory every time it needs an instance of my IResourceProvider, and - if possible - also to invoke IoC.Release(provider) or something similar when it's done with it.
How do I micro-manage the lifestyle of the custom IResourceProvider in a way that the MVC framework will respect?
After searching around for various ways to control the lifetime of the IResourceProvider itself, I decided that it was better to refactor my implementation to utilize the Typed Factory Facility.
My IResourceProvider implementation formerly looked something like this:
public class CachedResourceProvider : IResourceProvider {
CachedResourceProvider(IResourceRecordRepository repo) { /* ... */ }
// other members...
}
Now, I changed it to this instead:
public class CachedResourceProvider : IResourceProvider {
CachedResourceProvider(IResourceRecordRepositoryFactory repo) { /* ... */ }
// other members...
}
The factory interface is a new one, defined as
public interface IResourceRecordRepositoryFactory {
IResourceRecord NewInstance();
void Release(IResourceRecord instance);
}
and every usage of the private _repo instance in the CachedResourceProvider was refactored to three statements: get a repo instance from the factory, use the repo instance to fetch/save something, release the instance through the factory.
I registered them like this:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IResourceRecordRepositoryFactory>().AsFactory());
Now, even though MVC is keeping a reference to my resource provider across web requests, the services it uses are re-fetched from the Windsor container each time they're used, so the container is in full control of their lifetime.
I am working on an app which uses active directory to retrieve users. Sometimes I need to work on the app but AD is not available. I use a wrapper class to retrieve the AD user. I would like to inject a different class based on the configuration. I was thinking on using an appSetting that would tell me the current configutarion and decide what type to use when injecting. Is it possible to get the current configuration without using a Web.config transform? Is it possible to inject objects using Unity based on Web.config transformations? Can you recommend a better approach?
[UPDATE]
I have a user repository class that loads the users from AD. All I need is to be able to change the implementation of this repository class so that when AD is unavailable I can load the users a different way. This would only be used for development, production would always access AD and retrieve users.
You can use preprocessor directives:
#if DEBUG
// register fake repository
#else
// register AD repository
#endif
Well, Dependency Injection is incredibly powerful, agile, and creates a separation of concerns. The pitfall in your approach will come from validation. You see, with this approach you have to choose a concrete implementation.
So how will you call those two classes?
public class LogToText : ILogger
{
public void LogMessage(string message) { }
}
public class LogToEvent : ILogger
{
public void LogMessage(string message) { }
}
You have these two implementations, but when you pass the interface to:
public class AD
{
public AD(ILogger logger) { }
}
So the question will be do you feel that you can properly validate to choose the proper implementation effectively. Otherwise, Dependency Injection may not work well. We don't entirely know the usage or goal, so our advice may not be truly beneficial. Hopefully you see what I mean, because you'll have to see if you can't test a particular way.
You could use an Abstraction for this:
public interface IPersonService
{
IEnumerable<Person> Find(PersonSearchParameters searchParams);
Person GetByAccountName(string accountName);
[ETC...]
}
Then both your AD and Development implements this interface.
To make things easier, I suggest using StructureMap IoC, so you can easily do this:
x.For<IPersonService>.Use<ActiveDirectoryPersonService>(); //for production
or
x.For<IPersonService>.Use<MockPersonService>(); //for development
When using this you can, for instancce:
public class TestController : Controller
{
IPersonService _service;
public TestController(IPersonService service)
{
_service = service;
}
}
Instead of using an XML file for configuration in this case, I suggest using the Fluent code of Structure Map, it's better when refactoring and to avoid mistyping because it compiles.
StructureMap:
http://structuremap.net
Easy Installable via NuGET
A different approach would be to use the build configuration, read back from the assembly.
var buildConfiguration = typeof(Program).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration;
if (buildConfiguration == "Debug")
{
// register fake repository
}
else
{
// register AD repository
}
Then it is safer to apply refactorings or automatic code clean up (e.g. ReSharper etc.). Depending on your current configuration, code cleanup can otherwise remove unused usings. What then leads to build issues if an other configuration is used.
The application is an ASP.NET MVC webapp built up by repositories fronted by a concrete service layer for backend. I use structure map 3 as IoC to inject the repositories for each concrete service. For logging/caching etc. I use decorated repositories which also is setup with structure map.
The application has a public and non-public part. The non-public part is where some super users log in and create and update content. The public part consists of http handlers and is exposed on the web and handles 99.99% of all requests to the application.
I would like to configure structure map to use cache decorated repositories when instances are resolved in the http handlers but not in the rest of the application. I would also like to inject a different logger to the service when resolved in http handlers.
Is this possible to get different setups of the same interface implementation depending on the consumer?
public interface IEntityRepository<IEntity>
{
}
public class ContentService : IEntityService
{
public ContentService(IEntityRepository<Content> repoistory, ILogger logger)
{
}
}
NOTE that this solution doesn't provide the feature you are looking for - the delegate that is passed into the DecorateAllWith is only called once for each type that is resolved.
The DecorateAllWith method has an overload that can be used to analyse the type being created and filter accordingly
[Fact]
public void DecorateAllWith_Filtered_IsNotReturned()
{
var container = new StructureMap.Container(registry =>
{
registry.Scan(x =>
{
x.TheCallingAssembly();
x.ConnectImplementationsToTypesClosing(typeof(IEntityRepository<>));
});
registry.For(typeof(IEntityRepository<>))
.DecorateAllWith(typeof(CachingDecorator<>), instance => false);
});
var result = container.GetInstance<IEntityRepository<Entity1>>();
Assert.IsNotType<CachingDecorator<Entity1>>(result);
}
We are implementing ntier architecture for one of the project which uses EF6 ORM. DbContext scope is managed by ContextStoreFactory. Based on configuration ContextStoreFactory uses HttpContextStore/StaticContextStore to create DbContext. For console app its working fine. Now we planning for implemnting a wcf service with net.msmq binding which uses underneath services to process incoming request.
public class TestService : ITestService
{
public void ProcessPerson(Person person)
{
var repo = GetRepository();
var personService = new PersonService(repo);
personService.Process(person);
}
private IRepository GetRepository()
{
var context = ContextStoreFactory.GetContextStore().GetContext();//Calls OperationcontextStore
return new Repository(context);
}
}
I would like to manage the DbContext scope in wcf service. I come across many articles which says its best to use DBContext per call/operation. My sample OperationContextStore looks like follows. Please feel free to correct if it requires any correction.
public class OperationContextStore
{
public static readonly string ITEM_NAME = "DBCONTEXT-INSTANCES";
public DBContext GetContext()
{
if(!OperationContext.Current.OutgoingMessageProperties.ContainsKey(ITEM_NAME))
OperationContext.Current.OutgoingMessageProperties.Add(ITEM_NAME, new DBContext());
return (DBContext)OperationContext.Current.OutgoingMessageProperties[ITEM_NAME];
}
public void Dispose()
{}
}
I would like to know Is DbContext scope per call is valid in my scenario?
Is the approach to create Repository in my service method is valid?
Are there any best practices to wire this up without using IOC?
I know it's late to answer my own question and I will try to recollect what I did
I would like to know Is DbContext scope per call is valid in my scenario?
Yes,It was valid in my scenario.
Is the approach to create Repository in my service method is valid?
I ended up having IRepository as a property in my service class and did a property injection.
Are there any best practices to wire this up without using IOC?
I ended up writing my own utility. Please search for poor man's dependency injection.