NHibernate, injecting service into IUserType using .NET Core ioc container - nhibernate

Is it possible to inject a service into a UserType ?
internal class MyUserType : IUserType
{
private static ISerializer _serializer;
public MyUserType (ISerializer serializer)
{
_serializer = serializer
}
}
Tried the why it is suppose to work for all but fails, stating it needs a default parameterless constructor

I don't think this is going to be possible as you would need to tap into NH's component creation pipeline/process, which, AFAIK, isn't readily exposed.
You could use property injection with a 'local default'. This would allow you to depend on the ISerializer abstraction and replace it when necessary, testing maybe, but rely on a default concrete type in an environment that didn't support IoC.
internal class MyUserType : IUserType
{
private static ISerializer _serializer = new ConcreteSerializer();
public JsonShippingDetailsUserType()
{
}
public ISerializer Serializer { get; set; }
}
N.B. This is a really naive implementation of property injection. If you go with this solution you'll need to 'harden' the code. Mark Seemann's DI book has an excellent example.

The thing is that IUserType is managed by NHibernate which uses its own IoC container and by implication does not have access to your IoC of choice and again by implication does not have access to any services registered on your IoC of choice. There is not easy way of injecting, what I can think of is some sort of proxy or to somehow get access to NHibernate internals.

Related

Inject DbContext in Asp.Net Core. Concrete type or interface?

On an Asp.Net Core project I am injecting Entity Framework DbContext:
public MessageRepository(MyDbContext context) {
}
And the configuration is:
services
.AddEntityFramework()
.AddSqlServer()
.AddDbContext<Context>(x => x.UseSqlServer(connectionString);
Should I create an interface, IMyDbContext, and injecting it instead?
public class MyDbContext : DbContext, IMyDbContext { }
public MessageRepository(IMyDbContext context) {
}
In all ASP.NET Core examples I see the concrete type, MyDbContext, is being injected and not an interface ...
What option should I choose?
Currently working on a project myself, where I decided to go with 2 interfaces like this
public interface IDbContext : IDisposable
{
DbContext Instance { get; }
}
and
public interface IApplicationDbContext : IDbContext
{
DbSet<MyEntity> MyEntities { get; set; }
...
}
My concrete DbContext would then just implement the application context interface
public class ApplicationDbContext : DbContext, IApplicationDbContext
{
public DbContext Instance => this
public DbSet<MyEntity> MyEntities { get; set; }
}
This allows my implementation of the Application context to be injected as the application context interface, while also providing me access to the DbContext methods through the Instance property getter without having to add methods needed from the DbContext class to the interface.
Until now, this works great.
We're always injecting an interface, since it's easier to mock in unit and integration tests.
Are you willing to change the signature of the MessageRepository constructor? It relies on the concrete type.
Do you write tests for your code? Using and interface would make it easier to mock the database context.
If you've answered "no" to one or more of the above, inject the concrete type; otherwise, inject the interface.
[EDIT]
use the following.
context services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());
In my opinion, you should always rely on an interface as #Uli said, but when it comes to the DbContext you need to take in mind that you are exposing all methods of the DbContext of EntityFramework Core
public class MyDbContext : DbContext, IMyDbContext { }
in that case, you don't need to implement any method that you are exposing because DbContext handles that for you.
BUT if EF code change the DbContext and you make an update to your project then you will be on a painful situation of updating your IMyDbContext every time, also all your unit testing. In my opinion, that will give you a lot of headaches.
This answers/questions can help you to understand why https://stackoverflow.com/a/6768712/819153
Unit testing EF - how to extract EF code out from BL?

What is the benefit of using a Ninject.Factory over just injecting the IKernel?

According to this article (first paragraph), it is bad practice to inject your IKernel into wherever you need it.
Instead it is proposed to introduce a factory interface that is automatically implementend by Ninject (doing internally the same resolution).
This is an actual code snipped I am working on:
Former implementation:
public class CommandServer
{
[Inject]
public IKernel Kernel { get; set; }
....
public TResponse ExecuteCommand<TRequest, TResponse>(TRequest request)
where TResponse : ResponseBase, new()
{
...
var command = Kernel.Get<ICommand<TRequest, TResponse>>();
...
}
}
Using a factory:
public class CommandServer
{
[Inject]
public ICommandFactory CommandFactory { get; set; }
....
public TResponse ExecuteCommand<TRequest, TResponse>(TRequest request)
where TResponse : ResponseBase, new()
{
...
var command = CommandFactory.CreateCommand<TRequest, TResponse>();
...
}
}
// at binding time:
public interface ICommandFactory
{
ICommand<TRequest, TResponse> CreateCommand<TRequest, TResponse>();
}
Bind<ICommandFactory>().ToFactory();
I am not saying I don't like it (it looks nice and clean) - just not exactly sure why the former is particularly bad and the latter is so much better?
Generally you should not be using the Service Locator pattern. Why you ask? Please see Mark Seeman(comments, too!) and this SO question. Using the IKernel (or somewhat better: only the IResolutionRoot part of it) smells like Service Locator.
Now Mark would suggest that you should apply the Abstract Factory Pattern instead - and he also mentions the Dynamic proxy approach.
I personally think that using ninject auto-generated factories (= dynamic proxy approach) instead is worth the trade off.
You should not use a factory like:
public interface IServiceLocator
{
T Create<T>();
}
because well.. it's service locator ;-)
However, using something like
public interface IResponseHandleFactory
{
IResponseHandle Create(int responseId);
}
is perfectly fine.
Of course you can also do this by using the IResolutionRoot directly - instead of the factory. The code would look like:
IResolutionRoot.Get<IResponseHandle>(
new ConstructorArgument("responseId", theResponseIdValue);
Reasons not to use IResolutionRoot directly
A lot of the IResolutionRoot "methods" are in fact extension methods. That complicates unit-testing a lot (it's basically not a sensible choice if you want to unit test it, at all).
slight worse decoupling from container (=> ease of changing DI containers) than when using a factory interface. The auto-generated factory feature you can also implement as an add on to other containers - if they don't have it already (i've done so personally for Unity and AutoFac). However it requires some know-how about dynamic proxies.
Alternative to factory interfaces: Using Func<> factories. The above example could also be replaced by Func<int, IResponseHandle>(). Quite a lot DI containers support this out of the box / with standard plugins (ninject needs the Factory extension). So you'd be decoupled from the container even more. Disadvantage: harder to unit test and not clearly named parameters.

Changing IoC provider on an Caliburn Micro WPF Application

I've an existing WPF application based on caliburn micro MVVM pattern which was using Ideablade/cocktail for accessing to database. Now I've switched to servicestack and I was keeping on cocktail just for the composition pattern. Since I've noticed it takes quite a bit long to start the application I've done some test and Ninject performs better.
I find extremly usefull the MEF approach of defining the Export/ImportingConstrucor approach but and I was wondering how I can have it with Ninject... is it possible?
In my current implementation I've something as
[Export(typeof(IMyInterface))]
[Export(typeof(MyFirstViewModel))]
public class MyFirstViewModel:IMyInterface
{
[ImportingConstructor]
public MyFirstViewModel(IEventAggregator eventAggregator)รน
{
}
}
I've seend that in ninject I've to define something as
mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>();
mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>();
Can it be automatic?
Can I also define a funct to resolve when not found?
Thanks
StackTrace :
at Caliburn.Micro.IoC.<.cctor>b__0(Type service, String key) in c:\Users\Rob\Documents \CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 13
at Caliburn.Micro.IoC.Get[T](String key) in c:\Users\Rob\Documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 32
at myApp.Modules.Core.Framework.ViewModels.myAppScreenBase`1..ctor() in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Core\Framework\ViewModels\myAppScreenBase.cs:line 44
at myApp.Modules.Core.Framework.ViewModels.myAppSimpleScreen`1..ctor() in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Core\Framework\ViewModels\myAppSimpleScreen.cs:line 8
at myApp.Modules.AdE.ViewModels.CMATCLIDDelegheViewModel..ctor(IAdERepository repository, IDialogManager dialogManager, ICommonRepository commonRepository) in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Modules.AdE\ViewModels\CMATCLIDDelegheViewModel.cs:line 56
at DynamicInjector1033b54d439c44dbaa064db1c7e82f18(Object[] )
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.ResolveInternal(Object scope)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass15.<Resolve>b__f(IBinding binding)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
RepositoryExport :
public class RepositoryBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
foreach (var attribute in type.GetCustomAttributes(typeof(RepositoryAttribute), false)
.OfType<RepositoryAttribute>())
{
yield return bindingRoot
.Bind(attribute.ContractType ?? type)
.To(type).InSingletonScope();
}
}
}
but I got this compile error
Error 19 Cannot implicitly convert type 'Ninject.Syntax.IBindingNamedWithOrOnSyntax' to 'Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax'. An explicit conversion exists (are you missing a cast?)
Depending on the configuration of ninject (by default its enabled) you don't need to bind a type to itself, ninject will resolve it automatically. So mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>(); is superfluous. Remark: Creating the binding anyway also works.
However, if you want to bind Bar to IFoo or Foo to IFoo you need to bind it.
With it you can tell ninject to look for all types with an [Export] attribute and bind these.
Here comes the ninject conventions extension to the rescue. Get the ninject.extensions.conventions nuget package.
Then create a convention binding:
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.WithAttribute<ExportAttribute>()
.BindWith<ExportBindingGenerator>());
public class ExportBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
foreach (var attribute in type.GetCustomAttributes<ExportAttribute>())
{
yield return bindingRoot
.Bind(attribute.ContractType)
.To(type);
}
}
}
Things get a bit more complicated when you need to also use the [ImportingConstructor] attribute to tell ninject which constructor to use. But i would suppose that you don't need it, since Ninject's auto-constructor-selection. What you can do however is replace all [ImportingConstructor] attributes with Ninject's [Inject] attribute which does exactly the same.
Notes:
You may need to use another method than .FromThisAssembly() to specify all the assemblies which contain the implementation types.
If the implementation types are not public, you need to add IncludeNonePublicTypes() to the convention.

Using Ninject to bind an interface to multiple implementations unknown at compile time

I just recently started using Ninject (v2.2.0.0) in my ASP.NET MVC 3 application. So far I'm thrilled with it, but I ran into a situation I can't seem to figure out.
What I'd like to do is bind an interface to concrete implementations and have Ninject be able to inject the concrete implementation into a constructor using a factory (that will also be registered with Ninject). The problem is that I'd like my constructor to reference the concrete type, not the interface.
Here is an example:
public class SomeInterfaceFactory<T> where T: ISomeInterface, new()
{
public T CreateInstance()
{
// Activation and initialization logic here
}
}
public interface ISomeInterface
{
}
public class SomeImplementationA : ISomeInterface
{
public string PropertyA { get; set; }
}
public class SomeImplementationB : ISomeInterface
{
public string PropertyB { get; set; }
}
public class Foo
{
public Foo(SomeImplementationA implA)
{
Console.WriteLine(implA.PropertyA);
}
}
public class Bar
{
public Bar(SomeImplementationB implB)
{
Console.WriteLine(implB.PropertyB);
}
}
Elsewhere, I'd like to bind using just the interface:
kernel.Bind<Foo>().ToSelf();
kernel.Bind<Bar>().ToSelf();
kernel.Bind(typeof(SomeInterfaceFactory<>)).ToSelf();
kernel.Bind<ISomeInterface>().To ...something that will create and use the factory
Then, when requesting an instance of Foo from Ninject, it would see that one of the constructors parameters implements a bound interface, fetch the factory, and instantiate the correct concrete type (SomeImplementationA) and pass it to Foo's constructor.
The reason behind this is that I will have many implementations of ISomeInterface and I'd prefer to avoid having to bind each one individually. Some of these implementations may not be known at compile time.
I tried using:
kernel.Bind<ISomeInterface>().ToProvider<SomeProvider>();
The provider retrieves the factory based on the requested service type then calls its CreateInstance method, returning the concrete type:
public class SomeProvider : Provider<ISomeInterface>
{
protected override ISomeInterface CreateInstance(IContext context)
{
var factory = context.Kernel.Get(typeof(SomeInterfaceFactory<>)
.MakeGenericType(context.Request.Service));
var method = factory.GetType().GetMethod("CreateInstance");
return (ISomeInterface)method.Invoke();
}
}
However, my provider was never invoked.
I'm curious if Ninject can support this situation and, if so, how I might go about solving this problem.
I hope this is enough information to explain my situation. Please let me know if I should elaborate further.
Thank you!
It seems you have misunderstood how ninject works. In case you create Foo it sees that it requires a SomeImplementationA and will try to create an instance for it. So you need to define a binding for SomeImplementationA and not for ISomeInterface.
Also most likely your implementation breaks the Dependency Inversion Princple because you rely upon concrete instances instead of abstractions.
The solution to register all similar types at once (and the prefered way to configure IoC containers) is to use configuration by conventions. See the Ninject.Extensions.Conventions extenstion.

How to change configs in Spring.Net

An advantage of an IoC container is that you can swap in a mock service at the bottom of your object graph. However this seems much harder to do in Spring.Net than in other IoC Containers. Here's some code that does it in Unity and has Spring.Net code;
namespace IocSpringDemo
{
using Microsoft.Practices.Unity;
using NUnit.Framework;
using Spring.Context;
using Spring.Context.Support;
public interface ISomeService
{
string DoSomething();
}
public class ServiceImplementationA : ISomeService
{
public string DoSomething()
{
return "Hello A";
}
}
public class ServiceImplementationB : ISomeService
{
public string DoSomething()
{
return "Hello B";
}
}
public class RootObject
{
public ISomeService SomeService { get; private set; }
public RootObject(ISomeService service)
{
SomeService = service;
}
}
[TestFixture]
public class UnityAndSpringDemo
{
[Test]
public void UnityResolveA()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementationA>();
RootObject rootObject = container.Resolve<RootObject>();
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void UnityResolveB()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementationB>();
RootObject rootObject = container.Resolve<RootObject>();
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveA()
{
IApplicationContext container = ContextRegistry.GetContext();
RootObject rootObject = (RootObject)container.GetObject("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
// does not work - what to do to make this pass?
IApplicationContext container = ContextRegistry.GetContext();
RootObject rootObject = (RootObject)container.GetObject("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
}
}
For the benefit of Spring, the following needed to be in the App.config file. Clearly this only serves the first spring test, and not the second. Can you put multiple spring configurations in the config file? If so, what is the syntax and how do you access them? Or is there another way to do this?
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object name="RootObject" type="IocSpringDemo.RootObject, IocDemo" autowire="constructor" />
<object name="service" type="IocSpringDemo.ServiceImplementationA, IocDemo" autowire="constructor" />
</objects>
</spring>
Update
Here is a partial answer based at code at the links that Marko Lahma gave to Mark Pollack's blog. I have the above tests passing, with the following code:
public static class SpringHelper
{
public static T Resolve<T>(this IApplicationContext context, string name)
{
return (T)context.GetObject(name);
}
public static void RegisterType<T>(this GenericApplicationContext context, string name)
{
context.RegisterType(name, typeof(T));
}
public static void RegisterType(this GenericApplicationContext context, string name, Type type)
{
IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory();
ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, type);
builder.SetAutowireMode(AutoWiringMode.AutoDetect);
context.RegisterObjectDefinition(name, builder.ObjectDefinition);
}
}
...
[Test]
public void SpringResolveA()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType<RootObject>("RootObject");
container.RegisterType<ServiceImplementationA>("service");
RootObject rootObject = container.Resolve<RootObject>("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType<RootObject>("RootObject");
container.RegisterType<ServiceImplementationB>("service");
RootObject rootObject = container.Resolve<RootObject>("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
This raises a few questions to me:
I want to integrate this technique into existing code that uses the usual container. Why do I have to use a different container type, GenericApplicationContext in this case? What if I want to read data into this object from the existing spring config in app.config or web.config? Would it work as the usual context? Could I then write data over these registrations with code?
How can I specify that ISomeService is to be created as a singleton? I don't mean supply a singleton instance to the container, but the container to create the instance, resolving its constructor, and use it when that type is needed.
how can I do the equivalent of container.RegisterType<ISomeService, ServiceImplementationA>(); ? I want to register type mappings to use in all cases where that type is needed by a constructor.
What exactly does container.RegisterType<ServiceImplementationA>("service"); do? It seems to register ServiceImplementationA as the implementation of ISomeService but ISomeServiceis never mentioned, so there could be ambiguity. e.g. what if ServiceImplementationA implemented more than one interface.
What is the string name given to the registration for? It won't work with en empty string, but it doesn't seem to matter what it is.
Am I trying to use spring in a way that it just does not work? I'm trying to use it like other IoC containers, but it's not quite working.
Adding as new answer trying to address the open points...
I want to integrate this technique
into existing code that uses the usual
container. Why do I have to use a
different container type,
GenericApplicationContext in this
case? What if I want to read data into
this object from the existing spring
config in app.config or web.config?
Would it work as the usual context?
Could I then write data over these
registrations with code?
Spring has concrete application context implementations for different kind of initialization tactics. The most common ones to use are GenericApplicationContext (manual), XmlApplicationContext (XML files) and WebApplicationContext (very much like XmlApplicationContext but tailored for web use). They all implement common interface: IApplicationContext which is the preferred way to access these containers.
Unfortonately altering registrations with code usually means that you need to use the specific sub-class directly. With GenericApplicationContext and StaticApplicationContext this is quite natural but XmlApplicationContext is usually considered to be XML only and this ways "fixed" to XML definition.
How can I specify that ISomeService is
to be created as a singleton? I don't
mean supply a singleton instance to
the container, but the container to
create the instance, resolving its
constructor, and use it when that type
is needed.
Your SpringHelper does just that, by default all objects in Spring are singletons. You could alter this behavior by calling ObjectDefinitionBuilder's SetSingleton method with false.
how can I do the equivalent of
container.RegisterType(); ? I want to
register type mappings to use in all
cases where that type is needed by a
constructor.
Spring uses object names (ids) to distinct between different implementations. So if you want to get specific type to serve a specific instance in case that there are many alternatives you should refer to this specific instance by name. If you are using autowiring and your object has dependency to interface ISomeService and there's only one object registered that implements it, the autowiring can set it without ambiguity.
What exactly does
container.RegisterType("service");
do? It seems to register
ServiceImplementationA as the
implementation of ISomeService but
ISomeServiceis never mentioned, so
there could be ambiguity. e.g. what if
ServiceImplementationA implemented
more than one interface.
Continuing from previous answer, this registers singleton of type ServiceImplementationA with name "service". This object comes autowiring candidate with all it's implemented interfaces (and with it's concrete type of course).
What is the string name given to the
registration for? It won't work with
en empty string, but it doesn't seem
to matter what it is.
It matters a great deal as explained earlier. The name is unique id within that context (parent context could have object with same name) and can be used to access specific object registrations. In short where other frameworks may associate a type as key to object registration, Spring uses name.
That's a bit apples and oranges comparison as the unit test uses code configuration for Unity and XML (app.config) configuration for Spring.NET.
If you go the XML route, then you can either comment out old implementation A and define the B implementation as the one to use - that what's configuration is all about right? Other option is to have dedicated XML files for each scenario (configuration setup) and include them via context's resource definitions (you have inline resource now). Other options include file system and assembly, see the web configuration section in Spring.NET's manual for a nice example.
If you go the code configuration route I would suggest to check Spring.NET Recoil and upcoming CodeConfig.