Servicestack registration crashes with generic types - servicestack

If I have a base class for my services like
public abstract class BaseService<T,R> : ServiceStack.ServiceInterface.Service
{
public R Get(T request)
{
}
}
Then service stack crashes with
An attempt was made to load a program with an incorrect format.
I think Servicestack should ignore the abstract generic classes when registering services. Is there any way to tell servicestack to ignore some service classes ?

By default, ServiceStack is including all types in the assemblies as candidates for services. It gets that exception when it tries to instantiate the class.
By overriding the CreateServiceManager in the host class, you can inject your own filtering of types so that abstract and unclosed generics are excluded.
protected override ServiceManager CreateServiceManager(params Assembly[] assembliesWithServices)
{
return new ServiceManager(
new Container(),
new ServiceController(
() =>
assembliesWithServices.SelectMany(
assembly => assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition))));
}

Related

IoC container struggles with generics

I have an existing program with some plugin infrastructure that currently relies on plugin classes having parameterless constructors. I'd like to offer plugin authors the opportunity to just require some infrastructure from my program by specifying parameters for the constructor.
Internally, I use some generic wrapper class to encapsulate the plugin's classes and to make them behave to the rest of my program like older pre-plugin era internal classes.
I have some placeholder here representing my infrastructure:
public interface IInfrastructure
{
}
public class Infrastructure : IInfrastructure
{
}
Some plugin interface specification:
public interface IPlugin
{
}
the plugin implementation requiring my infrastructure:
public class Plugin : IPlugin
{
public Plugin(IInfrastructure _)
{
}
}
and my generic wrapper class expecting some plugin class
public class PluginWrapper<TImpl> where TImpl: class, IPlugin
{
public PluginWrapper(TImpl _)
{
}
}
After registering the involved types:
ServiceLocator.Default.RegisterType<IInfrastructure, Infrastructure>(RegistrationType.Transient);
ServiceLocator.Default.RegisterType(typeof(Plugin),typeof(Plugin), RegistrationType.Transient);
var wrapperType = typeof(PluginWrapper<>).MakeGenericType(typeof(Plugin));
ServiceLocator.Default.RegisterType(wrapperType, wrapperType,RegistrationType.Transient);
I find out that I can resolve the "inner" plugin type:
Assert.NotNull(ServiceLocator.Default.ResolveType<Plugin>());
but I can't resolve the "Wrapper" type.
Assert.NotNull(ServiceLocator.Default.ResolveType<PluginWrapper<Plugin>>());
Am I hitting a limitation of Catel's IoC container, or am I doing something wrong?
When not using the generic registration method, I passed the registration type in the position of the "tag" parameter by accident.
So, changing the registration part to this version:
ServiceLocator.Default.RegisterType<IInfrastructure, Infrastructure>(RegistrationType.Transient);
ServiceLocator.Default.RegisterType(typeof(Plugin),typeof(Plugin),registrationType:RegistrationType.Transient);
var wrapperType = typeof(PluginWrapper<>).MakeGenericType(typeof(Plugin));
ServiceLocator.Default.RegisterType(wrapperType, wrapperType, registrationType:RegistrationType.Transient);
fixes the problem and everything goes as expected.

Using StructureMap[4.7.0] Setter Injection in my MVC5 Controller

I am trying to inject the IApplicationConfigurationSection implementation into this MVC5 Controller, so that I can have access to some of the information (various strings) from my web.config custom section in all of my views:
public class BaseController : Controller
{
public IApplicationConfigurationSection AppConfig { get; set; }
public BaseController()
{
ViewBag.AppConfig = AppConfig; // AppConfig is always null
}
}
I want to use setter injection so I don't have to clutter up my derived Controller constructors with parameters that they don't really care about.
Note: If there is a better way to inject base class dependencies, please let me know. I admit I may not be on the right track here.
In my Global.asax I load my StructureMap configurations:
private static IContainer _container;
protected void Application_Start()
{
_container = new Container();
StructureMapConfig.Configure(_container, () => Container ?? _container);
// redacted other registrations
}
My StructureMapConfig class loads my registries:
public class StructureMapConfig
{
public static void Configure(IContainer container, Func<IContainer> func)
{
DependencyResolver.SetResolver(new StructureMapDependencyResolver(func));
container.Configure(cfg =>
{
cfg.AddRegistries(new Registry[]
{
new MvcRegistry(),
// other registries redacted
});
});
}
}
My MvcRegistry provides the mapping for StructureMap:
public class MvcRegistry : Registry
{
public MvcRegistry()
{
For<BundleCollection>().Use(BundleTable.Bundles);
For<RouteCollection>().Use(RouteTable.Routes);
For<IPrincipal>().Use(() => HttpContext.Current.User);
For<IIdentity>().Use(() => HttpContext.Current.User.Identity);
For<ICurrentUser>().Use<CurrentUser>();
For<HttpSessionStateBase>()
.Use(() => new HttpSessionStateWrapper(HttpContext.Current.Session));
For<HttpContextBase>()
.Use(() => new HttpContextWrapper(HttpContext.Current));
For<HttpServerUtilityBase>()
.Use(() => new HttpServerUtilityWrapper(HttpContext.Current.Server));
For<IApplicationConfigurationSection>()
.Use(GetConfig());
Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());
}
private IApplicationConfigurationSection GetConfig()
{
var config = ConfigurationManager.GetSection("application") as ApplicationConfigurationSection;
return config; // this always returns a valid instance
}
}
I have also "thrown my hands up" and tried using the [SetterProperty] attribute on the BaseController - that technique failed as well.
Despite my best efforts to find a solution, the AppConfig property in my controller's constructor is always null. I thought that
`Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());`
would do the trick, but it didn't.
I have found that if I discard setter injection and go with constructor injection, it works as advertised. I'd still like to know where I'm going wrong, but I'd like to stress that I'm not a StructureMap guru - there may be a better way to avoid having to constructor-inject my base class dependencies. If you know how I should be doing this but am not, please share.
While constructor injection in this scenario appears to be the better solution to the stated problem as it follows The Explicit Dependencies Principle
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
The mention of only needing to access the AppConfig in your views leads me to think that this is more of an XY problem and a cross cutting concern.
It appears that the controllers themselves have no need to use the dependency so stands to reason that there is no need to be injecting them into the controller explicitly just so that the dependency is available to the View.
Consider using an action filter that can resolve the dependency and make it available to the View via the same ViewBag as the request goes through the pipeline.
public class AccessesAppConfigAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var resolver = DependencyResolver.Current;
var appConfig = (IApplicationConfigurationSection)resolver.GetService(typeof(IApplicationConfigurationSection));
filterContext.Controller.ViewBag.AppConfig = appConfig;
}
}
This now makes the required information available to the views with out tight coupling of the controllers that may have a use for it. Removing the need to inject the dependency into derived classes.
Either via adorning Controller/Action with the filter attribute
[AccessesAppConfig] //available to all its actions
public class HomeController : Controller {
//[AccessesAppConfig] //Use directly if want to isolate to single action/view
public ActionResult Index() {
//...
return View();
}
}
or globally for all requests.
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new AccessesAppConfigAttribute());
}
}
At this point it really does not matter which IoC container is used. Once the dependency resolver has been configured, Views should have access to the required information in the ViewBag

How to handle 3rd Party assembly internally calling AutoMapper Initialize

I make use of a 3rd party DLL which internally uses AutoMapper and initializes it with AutoMapper.Initialize() but then from what I understand, I cannot also call Initialize() as it clear existing maps.
What is the best solution for a 3rd party to use AutoMapper without conflicting with my own code?
Or another way.. how should a shared assembly set itself up with AutoMapper which guarantees it's own profiles are initializes but allows the consumer of that assembly to initialize it's own profiles?
Should the 3rd party assembly just define it's profiles and rely on the calling code to initialize all enabled profiles - manually adding profiles from the 3rd part assembly?
I am using AutoMapper 5.1 at the moment.
The best way to do this is not to use the static instance of Mapper - create your own, and use Dependency Injection to inject an instance of IMapper wherever you need to use AutoMapper. This also makes it a lot easier to test your code.
This is how I do things using autofac as my DI container:
builder.Register<IMapper>(c =>
{
var profiles = c.Resolve<IEnumerable<Profile>>();
var config = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
});
return config.CreateMapper();
}).SingleInstance();
This way, whenever I need to use automapper, I just add it to my constructor:
public class MyClass
{
private readonly IMapper _mapper;
public MyClass(IMapper mapper)
{
_mapper = mapper;
}
public void DoSomething()
{
var mapped = _mapper.Map<Dto>(....);
}
}

HttpClient wrapper with Autofac for Web API

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

Automapper and access to member variables

I have an mvc controller which has a helper class injected into it. I would like to convert from a viewmodel to a dto using automapper. most of the properties are simple mappings but one involves calling the helper class with a parameter from the viewmodel. Ideally I would want to do something like this:
Mapper.CreateMap<TheViewModel, TheDto>()
.ForMember(dest => dest.Url, o => o.MapFrom(src => _urlHelper.GenerateUrlFromUsername(src.Username)));
...but I cannot because I cannot access a non-static field.
What is the best approach?
EDIT:
OK, so I have a custom resolver but how do I hook this in to my IoC container?
public class CustomResolver : ValueResolver<TheViewModel, string>
{
private readonly IUrlHelper _urlHelper;
public CustomResolver(IUrlHelper urlHelper)
{
_urlHelper = urlHelper;
}
protected override string ResolveCore(TheViewModel source)
{
return _urlHelper.GenerateUrlFromUsername(source.Username);
}
}
Use a custom resolver in this case:
http://automapper.codeplex.com/wikipage?title=Custom%20Value%20Resolvers
Custom resolvers can be instantiated from a container, so you can get whatever instance fields of services you need.

Resources