I'm trying to inject Signalr dependencies with Funq D.I.
The process is explained pretty well here and I tried also to follow this question.
and the Ninject version works pretty well.
Now I am trying to convert it to a Funq version using this gist for FunqDependencyResolver.
but this Funq version is not working and gives the "System.MissingMethodException: No parameterless constructor defined for this object" that should be because it's not registering dependencies.
Is this because the Ninject version is resolving to a method?
We used Windsor, but the process is the same for any IoC:
First create your resolver, inherit from signalR DefaultDependencyResolver:
public class CustomContainerResolver: DefaultDependencyResolver
{
public CustomContainerResolver(IocContainer instance)
{
_instance = instance;
}
public override object GetService(Type serviceType)
{
return _instance.Instance.Kernel.HasComponent(serviceType) ? _instance.GetService(serviceType) : base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return _instance.Instance.Kernel.HasComponent(serviceType) ? _instance.GetAllInstances(serviceType): base.GetServices(serviceType);
}
}
In your Startup:
var signalrDependency = new CustomContainerResolver(container);
then, as usual
app.MapSignalR(hubConfiguration);
Related
ServiceStack.Funq.Quartz Sample Code is
public class MyServices : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, {0}!".Fmt(request.Name) };
}
}
public class HelloJob : IJob
{
private MyServices MyServices { get; set; }
public HelloJob(MyServices myServices)
{
MyServices = myServices;
}
public void Execute(IJobExecutionContext context)
{
var response = MyServices.Any(new ServiceModel.Hello
{
Name = "CodeRevver"
});
response.PrintDump();
}
}
The above is works fine. if I in the MyServices Class, removed the Any function, and comment the Execute inner code.
public class MyServices : Service
{
}
the quartz.net will get the error:
[Quartz.Core.ErrorLogger】 An error occurred instantiating job to be executed. job= 'JobGroup1.GetUserJob111' Problem instantiating type 'ServiceStackWithQuartz.HelloJob'
why the class must have public object Any(Hello request) function ?
Thanks for using the package – I had no idea that other people would find it useful.
So If I understand correctly, in your situation you have:
public class MyServices : Service
{
}
And you’re trying to resolve this Service via constructor injection, which is effectively doing a:
container.Resolve<MyServices>();
This will fail because of the way the ServiceStack Funq IoC works. You can’t resolve a ServiceStack Service that has nothing in it (you'd probably never want to either) – It has to at least have one service implementation, It doesn’t matter what the implementation is.
Also, if you want to improve ServiceStack.Funq.Quartz, feel free to contribute to the code base.
Edit: It's probably worth mentioning that you can inject a "Non-Service" class with your logic in it if you want. You can resolve other classes that aren't based off of ServiceStack.Service even if there's nothing in them.
Edit 2: Responding to your "Service wont dispose" problem. This is the same across ServiceStack and has nothing to do with your Quartz Job. If you call a:
container.Resolve<MyServices>().Any(new new ServiceModel.Hello { });
from AppHost for example, your service wont dispose by itself. If you want it to dispose you can wrap it in a using statement. e.g.
using (var service = MyServices)
{
var response = MyServices.Any(new ServiceModel.Hello { });
}
The using will ensure that your service will be disposed afterwards.
Alternatively you can add the interface "IDispose" on to your Quartz Job and implement a Dispose() method that will do a:
MyServices.Dispose();
This will be called after a job has executed.
I'm inserting Automapper (latest version from Nuget) into my project (WebApi2, framework 4.5.1) and using SimpleInjector (latest version from Nuget).
My problem is that before using Automapper everything worked. Now I'm not sure why it is telling me that a reverse mapping is missing (when I know it's not needed for the service being called).
I'm using the IMappingEngine interface.
I have a AutoMapperConfig class with all the Mapper.CreateMap
Example of AutoMapperConfig
public static class AutoMapperConfig
{
public static void Configure(IMappingEngine mappingEngine)
{
Mapper.CreateMap<Entity, EntityModel>()
...
}
}
The reason AutoMapperConfig.Configure is receiving an IMappingEngine is that some mappings attributs have other mapping inside. For example (snippet of code):
(Note the Mapper.Map inside the Mapper.CreateMap)
Mapper.CreateMap<Req, ReqModel>()
.ForMember(
opt => opt.MapFrom(
src => new ServiceModel(mappingEngine)
{
Id = src.Plan.Id,
Name = src.Plan.Service.Name,
ServiceTypeId = src.Plan.Service.Type.Id,
Type = Mapper.Map<TypeModel>(src.Plan.Service.Type)
}))
In Global.asax (method Application_Start()) I'm calling:
AutoMapperConfig.Configure(Mapper.Engine);
In SimpleInjector registrations I'm using:
container.RegisterSingleton<IMappingEngine>(Mapper.Engine);
AutoMapper.Mapper.Configuration.ConstructServicesUsing(container.GetInstance);
Then each Controller receives a IMappingEngine and uses:
MappingEngine.Map
Anything missing or wrong?
Thanks in advance! Guillermo.
I have inherited a stub project which is a HttpClient wrapper specific to an API enpoint we maintain.
The intention is to distribute this solution as nuget to other .NET teams that would need to consume the API endpoint.
Looking at the Autofac wire-up as a Module below - my question is would the consumer do this:
var client = PlayersAPIHttpClientModule("http:/api.players.com");
How does this setup facilitate the consumer to pass the base URI and then access the GetPlayerInformation method?
using Autofac;
using AutoMapper;
using Alpha.Domain.Players;
using System.Net.Http;
namespace Alpha.Clients.Players
{
public class PlayersAPIHttpClientModule : Module
{
private readonly string _serviceBaseUrl;
public PlayersAPIHttpClientModule(string serviceBaseUrl)
{
this._serviceBaseUrl = serviceBaseUrl;
}
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.Register(ctx =>
{
var serviceClient = new HttpClient
{
BaseAddress =
new System.Uri(this._serviceBaseUrl)
};
return new
PlayerDomainManager(serviceClient,
ctx.Resolve<IMappingEngine>());
})
.SingleInstance()
.As<IPlayerDomainManager>();
}
}
}
This is the interface shared with the core domain.
public interface IPlayerDomainManager
{
IPlayer GetPlayerInformation (string playerId);
}
And this is the class itself with the exposed method functionality.
internal class PlayerDomainManager : IPlayerDomainManager
{
private readonly HttpClient _client;
private readonly IMappingEngine _mapper;
public PlayerDomainManager(HttpClient client, IMappingEngine mapper)
{
this._client = client;
this._mapper = mapper;
}
public IPlayer GetPlayerInformation(string playerId)
{
var response = this._client
.SendAsync
(new
HttpRequestMessage(HttpMethod.Get,
"/players/" + playerId),
CancellationToken.None)
.Result;
}
}
As described in the AutoFac Module documentation:
A module is a small class that can be used to bundle up a set of
related components behind a 'facade' to simplify configuration and
deployment. The module exposes a deliberate, restricted set of
configuration parameters that can vary independently of the components
used to implement the module.
As per the common use cases of Modules as described in the documentation, a common use case is to:
Configure related services that provide a subsystem, e.g. data access
with NHibernate
In the case of your code base, the PlayersAPIHttpClientModule is configuring the PlayerDomainManager as a service that implements the IPlayerDomainManager and configuring its lifetime to act as a singleton. The benefit is that the Module allows the deeply buried configuration requirement of the PlayerDomainManager (the base service url that in turn is required by one of its dependencies) to be surfaced as configuration centralised to the Modules constructor. This benefit would be more obvious if the configuration was more complex.
Modules need to be registered with AutoFac as per any other dependency:
builder.RegisterModule(new PlayersAPIHttpClientModule("base_service_url));
In turn, the services they configure are resolved using standard AutoFac dependency resolution.
scope.Resolve<IDomainPlayerManager>();
So, to answer your question, no you would not use the PlayersAPIHttpClientModule as per your question.
Register the PlayersAPIHttpClientModule with the AutoFac ContainerBuilder
Use the AutoFac Container to resolve the IDomainPlayerManager as required
I'm new on using ninject and Dependency Injection, and have a problem using it.
I try to using Ninject on my class libray, and building an integration tests.
now, I see in many example that, for using ninject is just specified the DI Module like this:
Public Class DIModule : NinjectModule
public override void Load()
{
Bind<IUSAServices>().To<USAServices>();
}
And then on my test class, I try to call my dependency is like this:
[TestClass]
public class USAIntegrationTests
{
private readonly IUSAServices _usaService;
public USAIntegrationTests(IUSAServices usaServices)
{
_usaService = usaServices;
}
[TestMethod]
public void ValidateUserTests()
{
Assert.IsTrue(_usaService.ValidateUser("username1", "password1"));
}
}
And Getting this error:
Unable to get default constructor for class USATests.IntegrationTests.USAIntegrationTests.
However I read the documentation and tried like this:
[TestClass]
public class USAIntegrationTests
{
private readonly IUSAServices _usaService;
public USAIntegrationTests()
{
using (IKernel kernel = new StandardKernel(new DIModule()))
{
_usaService = kernel.Get<IUSAServices>();
}
}
[TestMethod]
public void ValidateUserTests()
{
Assert.IsTrue(_usaService.ValidateUser("mantab", "banget"));
}
}
The test is works properly.
My question is, why I getting that error? is that some way to get around it?
Thanks in advance.
Unit test frameworks require your test classes to have a default constructor. You usually can't integrate DI containers with them. Instead of using constructor injection, you will have to call the container directly from your code, although for unit tests you should typically not have a container at all (for integration tests however, this is okay).
You can add a paramterless constructor for the class. It worked for me.
I am trying to use the Cache facilities of Service Stack. These are accessed through the
RequestContext, which is injected by the IOC in your Service.
This works as expected if you are using the default Funq IOC, it does not work when you hook AutoFac, RequestContext is null and I am not sure how to configure autofac to build it. Any clues here? My AutoFac configuration:
var builder = new ContainerBuilder();
//Now register all dependencies to your custom IoC container
builder.RegisterAssemblyTypes(new[] { typeof(AppHost).Assembly })
.PropertiesAutowired(PropertyWiringFlags.AllowCircularDependencies)
.AsImplementedInterfaces()
.SingleInstance();
container.Register<ICacheClient>(new MemoryCacheClient());
IContainerAdapter adapter = new AutofacIocAdapter(builder.Build());
container.Adapter = adapter;
EDIT:
My Service already extends ServiceStack.ServiceInterface.Service:
public class UserDetailsService : ServiceStack.ServiceInterface.Service
which implements IRequiresRequestContext, RequestContext is null. If I remove autofac then it works as expected. With Autofac RequestContext is null
RequestContext is not meant to be injected by an IOC, it's a special property that is set by ServiceStack if your Service requests it by implementing the IRequiresRequestContext interface. E.g.
public class MyClass : IService, IRequiresRequestContext {
//injected by ServiceStack at run-time (per request)
public IRequestContext RequestContext { get; set; }
}
This is the same mechanism how the RequestContext property gets populated in the convenient default Service base class in ServiceStack.