what is the best practice to set up DbContext in StructureMap for console app? - entity-framework-4.1

I use StructureMap, EF 4.1/POCO.
Console app supposes to run 2 consequent operations upon some set of data, lets say operation1 and operation2. I set DbContext up as an singleton. This causes problem in operation2 as operation1 left some trash in its DbContext that prevent operation2 works well. In the same time I can not set up DbContext as 'per call' coz operation1 uses 2 repositories sharing the same DbContext passing through their constructor. So ideally I need reinitialize/reset/cleanup DbContext before operation2. Any ideas?
Thanks

Simply use two different contexts. There is no better solution to reset context then creating a new one. If you are fighting with your current architecture simply improve it to support new scenario. Instead of passing context instance pass a context factory which will be able to create you as many context instances as you need. Same with repositories - you can have factory to create a new repository instances on demand.
Edit with example:
Let's suppose that you are using EFv4.1 Update 1. It offers new interface IDbContexFactory<TContext>. You can define your class this way:
public class YourClass
{
private readonly IDbContextFactory<IYourContext> _factory;
public YourClass(IDbContextFactory<IYourContext> factory)
{
_factory = factory;
}
public void Operation1()
{
using (IYourContext context = _factory.Create())
{
RepositoryA repository = new RepositoryA(context);
RepositoryB repository = new RepositoryB(context);
...
}
}
public void Operation2()
{
using (IYourContext context = _factory.Create())
{
RepositoryA repository = new RepositoryA(context);
RepositoryB repository = new RepositoryB(context);
...
}
}
}
This was example where you pass factory for context but you can do the same for repository if you want to.

Related

Does Jodd framework provide mechanism to inject petitebeans references for objects created by other frameworks

Does Jodd framework provide mechanism to inject petitebeans references for the objects created by other frameworks.
Below are scenarios
- Domain/Service objects are created by Spring Framework
- Domain objects created are by ORM Frameworks
- These objects need to be injected with Repository/DAO object (Singleton objects registered as PetiteBean via AutomagicPetiteConfigurator)
Below is sample code, after petite container is shutdown, initMethod() is invoked when pc.getBean(Greetings.class).message(null) is invoked and destroyMethod() is not invoked, can you please point me what I am doing wrong?
#PetiteBean("greetings")
public class EnglishGreetings implements Greetings {
#Override
public String message(String message) {
if (message == null) {
return "defaultMessage";
}
return message;
}
#PetiteInitMethod
public void initMethod() {
System.out.println("Entered initMethod");
}
#PetiteDestroyMethod
public void destroyMethod() {
System.out.println("Entered destroyMethod");
}
}
public class GreetingRunner {
final static Logger logger = LoggerFactory.getLogger(GreetingRunner.class);
#PetiteInject
public Greetings greetings;
public static void main(String s[]) {
jodd.log.LoggerFactory.setLoggerFactory(new Slf4jLoggerFactory());
PetiteContainer pc = new PetiteContainer();
AutomagicPetiteConfigurator configurator = new AutomagicPetiteConfigurator();
configurator.setIncludedEntries("com.rans.*");
configurator.configure(pc);
pc.shutdown();
System.out.println(pc.getBean(Greetings.class).message(null));
}
}
Destroy method has not been invoked because of lazy aspect of Petite - if bean has not been used, no destroy method will be called. The same applies to init methods. If bean is not used, Petite simple ignores it.
Now back to the question:
Does Jodd framework provide mechanism to inject petitebeans references for the objects created by other frameworks.
Technically, yes - if you overwrite it :) See PetiteProxettaContainer. You may override getBean and use 3rd party container to fetch the bean. Actually, you may override createBeanDefinitionForRegistration method to register the bean in the different container. To be honest, we might make this more obvious :)
(Sorry for late response)

Castle Windsor - how to resolve by name?

My application uses the "SignalR" client/server comms framework. If you aren't familiar with it, the server-side app typically contains one or more "hub" classes (similar to asmx web services), each providing methods that can be called by a client. During startup, the client needs to first create a connection, then create a "proxy" for each hub that it will need to talk to, e.g.:-
var hubConnection = new HubConnection("http://...");
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
var barHubProxy = hubConnection.CreateHubProxy("BarHub");
...etc...
The string parameter passed to CreateHubProxy() is the name of the server-side hub class. The method return type is IHubProxy.
It feels like I should be able to utilise Windsor here, but I'm struggling to find a solution. My first thought was to instantiate the hub proxies and register these instances with Windsor (by name), e.g.
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
container.Register(Component.For<IHubProxy>().Instance(fooHubProxy).LifestyleSingleton().Named("FooHub"));
...etc...
The problem is that when a class needs a hub proxy, the only way to resolve it by name is to use service locator pattern, which isn't recommended. What other Windsor features (e.g. typed factories, etc.) might be useful here?
Edit
I've just found Windsor's .UsingFactoryMethod, and am wondering if this would work, to simplify hub registration:
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
.LifestyleSingleton()
.Named("FooHub"));
I guess I still have the problem of how to resolve by name though.
Two years later, but I have a more elegant solution for other people that stummble accross this problem too.
It is possible to use TypedFactory facility and adapt it to you needs like here.
first create the factory interface (only! no need for the actual implementation, castle will take care of that):
public interface IHubProxyFactory
{
IHubProxy GetProxy(string proxyName);
}
Now we need a class that extend the default typed facotory and retreives the component's name from the input (proxyName):
class NamedTypeFactory : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
string componentName = null;
if (arguments!= null && arguments.Length > 0)
{
componentName = arguments[0] as string;
}
if (string.IsNullOrEmpty(componentName))
componentName = base.GetComponentName(method, arguments);
return componentName;
}
}
And then register the factory with castle and specify that your NamedTypeFactory will be used:
Component.For<IHubProxyFactory>().AsFactory(new NamedTypeFactory())
Now every class can get the factory interface in its constructor:
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(IHubProxyFactory hubProxyFactory)
{
_fooHub = hubProxyFactory.GetProxy("FooHub");
_barHub = hubProxyFactory.GetProxy("BarHub");
}
}
Okay, I think I've found a possible solution, partly using the approach detailed here which shows how it is possible to register Func<>s with Windsor.
First, I register a delegate (Func<>) that uses the container to resolve by name:-
Container.Register(Component.For<Func<string, IHubProxy>>()
.Instance(name => Container.Resolve<IHubProxy>(name))
.LifestyleSingleton());
Think of this as an IHubProxy "factory".
Next, I register my hub proxies as detailed in my original question:-
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
.LifestyleSingleton()
.Named("FooHub"));
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("BarHub"))
.LifestyleSingleton()
.Named("BarHub"));
Here is an example of a class that needs instances of the hub proxies:-
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(Func<string, IHubProxy> hubProxyFactory)
{
_fooHub = hubProxyFactory("FooHub");
_barHub = hubProxyFactory("BarHub");
}
}
Untried so far, but it looks promising. It's a clever solution but injecting the Func<> feels a little hacky, so I would still be keen to hear of other possible solutions to my problem.
I just used a similar method to yours. I use a typed Factory. Advantage is I have type safety for my hubs. Registering the hubs is the same. The rest differs a bit but is technical the same.
IServiceFactory {
IHubProxy GetFooHub();
IHubProxy GetBarHub();
}
And Registration:
Container.AddFacility<TypedFactoryFacility>();
Container.Register(Component.For<IServiceFactory>().AsFactory());
Usage:
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(IServiceFactry hubProxyFactory)
{
_fooHub = hubProxyFactory.GetFooHub();
_barHub = hubProxyFactory.GetBarHub();
}
}
Btw. Factory.Get"Name"() resolves by name.

Castle: using an existing (not single) instance for a lower-level dependency

I have a model roughly like this:
public interface IUnitOfWork { }
public class UnitOfWork : IUnitOfWork { }
public interface IService { }
public class Service : IService
{
public IUnitOfWork UnitOfWork { get; set; }
}
public class ViewModel
{
public IService Service { get; set; }
}
And a configuration that could be like this:
container.Register(Component.For<IService>().ImplementedBy<Service>()
.LifeStyle.Transient
Component.For<IUnitOfWork>().ImplementedBy<UnitOfWork>()
.LifeStyle.Transient,
Component.For<ViewModel>().LifeStyle.Transient);
I need to resolve, at different points, two instances of ViewModel (I'm using a typed factory for this, but let's leave that aside for simplicity and assume I'm using the raw container)
The catch is that I need to resolve two instances of ViewModel at different points (from another ViewModel that knows about both), and they need to share the same IUnitOfWork.
So, something like this:
var vm1 = container.Resolve<ViewModel>();
//...later
var vm2 = container.Resolve<ViewModel>();
Now, it's very easy to share the Service. I'd just have to do something like:
var vm2 = container.Resolve<ViewModel>(new { vm1.Service });
But of course the actual model is more complicated (different ViewModels, with more Services each), so that's not an option.
I can pass the UnitOfWork to Resolve, but it doesn't get used by default (which makes sense). Is there any way to use that parameter (probably by registering a delegate somewhere) when resolving the second ViewModel?
I'd like to be able to do the following:
var vm2 = container.Resolve<ViewModel>(new { UnitOfWork });
And get a ViewModel whose Service has that specific UnitOfWork.
If you need to share a component and you cannot set as singleton(rich client) or perwebrequest, you need to use Contextual lifestyle.
check this thread see my last comment to downoload contrib w/ Contextual Lifestyle
For you case I assume those 2 ViewModel will be used by 1 View... so View + UoW require Contextual Lifestyle
check also this one too see comments at the end
The solution was to use ContextualLifestyle coupled with a custom factory that kept a reference to the ContainerContext, in order to use the same one when resolving another ViewModel.

UNITY: passing in a new datacontext each time?

I am trying to use unity to automatically inject a datacontext on my repository using a new instance each time.., my idea is the ensure that each time a new datacontext is injected
Currently its failing on creating the repository, i think it can't resolve MyDataContext
Before creating a constructor on "the repository" (see below) to take in the DataContext on my repository everything worked but now its failing..
I currently have this setup in my unity container which i create in global.asax, i have also registered the type MyDataContext which is standard DataContext
container = new UnityContainer();
Container.RegisterType<MyDataContext, MyDataContext>()
.RegisterType<IOfficeRepository, OfficeRepository>()
.RegisterType<IOfficeService, OfficeService>();
basically i have a service that calls the repository like so
public class OfficeService : IOfficeService
{
IOfficeRepository repository = null;
public OfficeService(IOfficeRepository repository)
{
this.repository = repository;
if (this.repository == null)
throw new InvalidOperationException("Repository cannot be null");
}
here is my repository
public class OfficeRepository : IOfficeRepository
{
private MyDataContext db;
public OfficeRepository (MyDataContext dataContext)
{
this.db = dataContext;
}
EDIT
I almost forgot i am doing this to create the service
officeService = Bootstrapper.Container.Resolve<IOfficeService>();
EDIT - THE ERROR BEING GENERATED
Resolution of the dependency failed, type = "MarkSmith.IOfficeService", name = "".
Exception message is: The current build operation (build key Build
Key[MarkSmith.OfficeService, null]) failed: The parameter repository could not be
resolved when attempting to call constructor
MarkSmith.OfficeService(MarkSmith.IOfficeRepository repository). (Strategy type BuildPlanStrategy, index 3)
EDIT - REMOVING Constructor on repository works
It is something to do with the datacontext because if i remove the constrcutor on the repository that takes a DataContext then all works, but of course i need it to accept a DataContext to be able to inject a "NEW" datacontext each time
public class OfficeRepository : IOfficeRepository
{
private MyDataContext db new MyDataContext(); // CHANGE
//public OfficeRepository (MyDataContext dataContext)
//{
//this.db = dataContext;
//}
EDIT - ACTUAL ERROR
After digging deeper i have found this error ....
The type MyDataContext has multiple constructors of length 2.
Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0)
(Strategy type BuildPlanStrategy, index 3)
EDIT - TEST TO RESOLVE THE DATACONTEXT with 1 line of code
This also fails with the same error as above - multiple constructors
MyDataContext test = Bootstrapper.Container.Resolve<MyDataContext >();
EDIT - ALL CONSTRUCTORS ON MY DATACONTEXT
These were created by an exernal util but all should be well..
[System.Diagnostics.DebuggerNonUserCode]
public MyDataContext()
: base(ConnectionString, mappingCache)
{
OnCreated();
}
[System.Diagnostics.DebuggerNonUserCode]
public MyDataContext(string connection)
: base(connection, mappingCache)
{
OnCreated();
}
[System.Diagnostics.DebuggerNonUserCode]
public MyDataContext(System.Data.IDbConnection connection)
: base(connection, mappingCache)
{
OnCreated();
}
[System.Diagnostics.DebuggerNonUserCode]
public MyDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource)
: base(connection, mappingSource)
{
OnCreated();
}
[System.Diagnostics.DebuggerNonUserCode]
public MyDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource)
: base(connection, mappingSource)
{
OnCreated();
}
EDIT - To demonstrate creating the DataContext in code without Unity works 100% without issue
MyDataContext tes2t = new MyDataContext ();
I'm not sure this works, but have you tried to register MyDataContext as a component rather than a type mapping?
container.RegisterType<MyDataContext>();
instead of
container.RegisterType<MyDataContext, MyDataContext>();
EDIT based on new information
The culprit seems to be that MyDataContext has more than one constructor. This is a common issue with most DI Containers, because they need to pick and use only one. If you can remove the ambiguity by constraining MyDataContext to have only one constructor, that will probably be the simplest solution.
Otherwise, you should be able to use an InjectionConstructor instance to identify the constructor when you register the repository. Let's assume you want to use a constructor that takes a connection string as an argument:
string connectionString =
ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
var injectedConnectionString = new InjectionConstructor(connectionString);
container.RegisterType<MyDataContext>(injectedConnectionString);
With multiple constructors to choose from, Unity doesn't know which one to use. It will choose the one with the most arguments that can all be satisfied, but in this case there are two constructors each with two resolvable arguments.
If you don't want to couple your MyDataContext class to Unity and use the InjectionConstructor attribute as suggested by Scott (upvoted :)), you can specify the constructor that should be used at the time of registration using the fluent interface. See Configuring Constructor, Property, and Method Injection for details.
I don't see your MyDataContext constructors; but try to add the [InjectionConstructor] attribute to the one you want to use.

Castle Windsor and IPrincipal

Is is possible to inject IPrincipal using Castle Windsor into my asp.net mvc controller. This article by Scott Hanselman has code in the comments to do it with structure map, but I cannot figure out how to do it with Castle.
Update:
Here is what I ended up with for my controller factory. Note that most of the code is from Steve Sanderson's Pro ASP.NET MVC book with the addition of the code from the answers below.
public class WindsorControllerFactory : DefaultControllerFactory
{
readonly WindsorContainer _container;
// The constructor:
// 1. Sets up a new IoC container
// 2. Registers all components specified in web.config
// 3. Registers IPrincipal
// 4. Registers all controller types as components
public WindsorControllerFactory()
{
// Instantiate a container, taking configuration from web.config
_container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle"))
);
_container.AddFacility<FactorySupportFacility>();
_container.Register(Component.For<IPrincipal>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => HttpContext.Current.User));
// Also register all the controller types as transient
var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (var t in controllerTypes)
_container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
}
// Constructs the controller instance needed to service each request
protected override IController GetControllerInstance(Type controllerType)
{
return (IController)_container.Resolve(controllerType);
}
}
If you're using Windsor 2.0, there's no need to modify the ControllerFactory:
var container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IPrincipal>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => HttpContext.Current.User));
// your component registrations...
This is just a wrapper around the Factory facility configuration. If you're using a previous version (RC3) you can configure this with XML too.
You try to let Windsor construct your IPrincipal where it has to just use the one that's there.
Inject it into the container through the AddComponentInstance method exposed by the MicroKernel in your ControllerFactory.
This would obviously require a custom ControllerFactory, but you should have that already.
I did something similar for HttpContext some time ago:
http://www.tigraine.at/2009/01/21/aspnet-mvc-hide-the-httpcontext-services-with-windsor-and-a-custom-controllerfactory/comment-page-1/#comment-2645
Your controller factory could look like this:
public IController CreateController(RequestContext requestContext, string controllerName)
{
container.Kernel.AddComponentInstance<IPrincipal>(typeof (IPrincipal),
System.Web.HttpContext.Current.User);
return (IController) container.Resolve(controllerName);
}
(Don't forget that your controllers have to be per-web-request or transient for this or you'll get in trouble)