Simplifying configuration of WCF4 RESTful service routes - c#

The default Global.asax.cs file from the "WCF REST Template 40(CS)" project template and every tutorial I've seen online include a variation of the following method:
private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));
}
Managing the service routing in this way seems needlessly cumbersome when the WebApplication itself should be able to discover which services should be available and apply routes based on convention or metadata.
QUESTIONS
Is there a built-in way beyond the default to define the service routes (either configurable in the web.config, or compiled onto the service itself)?
Do others that use this template always follow the model provided or has someone else come up with a better approach?
Proposed Solution
Migrated my proposed solution to an answer

I guess I have to assume that silence is acceptance. Here is my solution (originally from my question):
Assuming there is nothing better built in or otherwise available (because I didn't find anything), my attempt at doing this involves defining an attribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class ServiceRouteAttribute : Attribute
{
public string RoutePrefix { get; set; }
public Type ServiceFactoryType { get; set; }
public ServiceHostFactoryBase ServiceFactory
{
get
{
if (ServiceFactoryType == null || !ServiceFactoryType.IsRelated(typeof(ServiceHostFactoryBase)))
return null;
return Activator.CreateInstance(ServiceFactoryType) as ServiceHostFactoryBase;
}
}
public ServiceRouteAttribute() : this(string.empty) { }
public ServiceRouteAttribute(string routePrefix) : this(routePrefix, typeof(WebServiceHostFactory)) { }
public ServiceRouteAttribute(string routePrefix, Type serviceFactoryType)
{
RoutePrefix = routePrefix;
ServiceFactoryType = serviceFactoryType;
}
}
which is used to decorate each service contract that should be exposed, and changing the default RegisterRoutes to:
private void RegisterRoutes()
{
// `TypeHelper.GetTypes().FilterTypes<T>` will find all of the types in the
// current AppDomain that:
// - Implement T if T is an interface
// - Are decorated with T if T is an attribute
// - Are children of T if T is anything else
foreach (var type in TypeHelper.GetTypes()
.FilterTypes<ServiceRouteAttribute>())
{
// routeAttrs should never be null or empty because only types decorated
// with `ServiceRouteAttribute` should ever get here.
// `GetAttribute<T>` is my extension method for `MemberInfo` which returns all
// decorations of `type` that are T or children of T
var routeAttrs = type.GetAttributes<ServiceRouteAttribute>();
foreach (var routeAttr in routeAttrs)
{
// Some dupe and error checking
var routePrefix = routeAttr.RoutePrefix;
if (string.IsNullOrEmpty(routePrefix))
routePrefix = type.Name;
RouteTable.Routes.Add(new ServiceRoute(routePrefix,
routeAttr.ServiceFactory,
type));
}
}
}
This seems to work and isn't too intrusive because it only happens at Application_Start, but I'm new to building RESTful web services with WCF4 so I don't know what sort of problems it could cause.
If anyone comes up with a more elegant way of solving this, I'd gladly consider any alternative.

Related

Asp WebApi: Filtering and injection dependency into constructor parameters [duplicate]

I have been looking around for a non Parameter injection option for the WebApi attributes.
My question is simply whether this is actually possible using Structuremap?
I have been googling around but keep coming up with either property injection (which I prefer not to use) or supposed implementations of constructor injection that I have thus far been unable to replicate.
My container of choice is Structuremap however any example of this will suffice as I am able to convert it.
Anyone ever managed this?
Yes, it is possible. You (like most people) are being thrown by Microsoft's marketing of Action Filter Attributes, which are conveniently put into a single class, but not at all DI-friendly.
The solution is to break the Action Filter Attribute into 2 parts as demonstrated in this post:
An attribute that contains no behavior to flag your controllers and action methods with.
A DI-friendly class that implements IActionFilter and contains the desired behavior.
The approach is to use the IActionFilter to test for the presence of the attribute, and then execute the desired behavior. The action filter can be supplied with all dependencies (through the constructor) and then injected when the application is composed.
IConfigProvider provider = new WebConfigProvider();
IActionFilter filter = new MaxLengthActionFilter(provider);
config.Filters.Add(filter);
NOTE: If you need any of the filter's dependencies to have a lifetime shorter than singleton, you will need to use a GlobalFilterProvider as in this answer.
To wire this up with StructureMap, you will need to return an instance of the container from your DI configuration module. The Application_Start method is still part of the composition root, so you can use the container anywhere within this method and it is still not considered a service locator pattern. Note that I don't show a complete WebApi setup here, because I am assuming you already have a working DI configuration with WebApi. If you need one, that is another question.
public class DIConfig()
{
public static IContainer Register()
{
// Create the DI container
var container = new Container();
// Setup configuration of DI
container.Configure(r => r.AddRegistry<SomeRegistry>());
// Add additional registries here...
#if DEBUG
container.AssertConfigurationIsValid();
#endif
// Return our DI container instance to the composition root
return container;
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// Hang on to the container instance so you can resolve
// instances while still in the composition root
IContainer container = DIConfig.Register();
AreaRegistration.RegisterAllAreas();
// Pass the container so we can resolve our IActionFilter
WebApiConfig.Register(GlobalConfiguration.Configuration, container);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
}
public static class WebApiConfig
{
// Add a parameter for IContainer
public static void Register(HttpConfiguration config, IContainer container)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// Add our action filter
config.Filters.Add(container.GetInstance<IMaxLengthActionFilter>());
// Add additional filters here that look for other attributes...
}
}
The implementation of MaxLengthActionFilter would look something like this:
// Used to uniquely identify the filter in StructureMap
public interface IMaxLengthActionFilter : System.Web.Http.Filters.IActionFilter
{
}
public class MaxLengthActionFitler : IMaxLengthActionFilter
{
public readonly IConfigProvider configProvider;
public MaxLengthActionFilter(IConfigProvider configProvider)
{
if (configProvider == null)
throw new ArgumentNullException("configProvider");
this.configProvider = configProvider;
}
public Task<HttpResponseMessage> ExecuteActionFilterAsync(
HttpActionContext actionContext,
CancellationToken cancellationToken,
Func<Task<HttpResponseMessage>> continuation)
{
var attribute = this.GetMaxLengthAttribute(filterContext.ActionDescriptor);
if (attribute != null)
{
var maxLength = attribute.MaxLength;
// Execute your behavior here (before the continuation),
// and use the configProvider as needed
return continuation().ContinueWith(t =>
{
// Execute your behavior here (after the continuation),
// and use the configProvider as needed
return t.Result;
});
}
return continuation();
}
public bool AllowMultiple
{
get { return true; }
}
public MaxLengthAttribute GetMaxLengthAttribute(ActionDescriptor actionDescriptor)
{
MaxLengthAttribute result = null;
// Check if the attribute exists on the action method
result = (MaxLengthAttribute)actionDescriptor
.GetCustomAttributes(typeof(MaxLengthAttribute), false)
.SingleOrDefault();
if (result != null)
{
return result;
}
// Check if the attribute exists on the controller
result = (MaxLengthAttribute)actionDescriptor
.ControllerDescriptor
.GetCustomAttributes(typeof(MaxLengthAttribute), false)
.SingleOrDefault();
return result;
}
}
And, your attribute which should not contain any behavior should look something like this:
// This attribute should contain no behavior. No behavior, nothing needs to be injected.
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MaxLengthAttribute : Attribute
{
public MaxLengthAttribute(int maxLength)
{
this.MaxLength = maxLength;
}
public int MaxLength { get; private set; }
}
I struggled with custom action filter providers, without getting it to work for my auth attributes. I also trying out various approaches with constructor and property injection, but did not find a solution that felt nice.
I finally ended up injecting functions into my attributes. That way, unit tests can inject a function that returns a fake or mock, while the application can inject a function that resolves the dependency with the IoC container.
I just wrote about this approach here: http://danielsaidi.com/blog/2015/09/11/asp-net-and-webapi-attributes-with-structuremap
It works really well in my project and solves all problems I had with the other approaches.

Configuring MassTransit's Ninject bindings after initialisation

I want to configure MassTransit at one point in my code (using WebActivator) and configure the message handlers in another (a Ninject module). Is there a way I can achieve this? The documentation here shows how to perform what I need in one step, but to do anyhting else, it looks like I need to get an instance of a ServiceBusConfigurator, which doesn't seem to be available from the preexisting IServiceBus
Configuration and Creation of the IServiceBus cannot be separated.
That means, the only option you have is to gather the configuration information some more time before creating the bus.
As the doc you linked states, the meta data information made available by ninject is not sufficient to create the subscriptions. This basically means that you've got to create your own metadata model. Let's make an example, which can be used with single registrations but also with convention based registrations:
Hint: You should treat the following code snippets as psuedo code as i've written them from memory. It's highly likely that it won't compile.
Metadata Model
public class SubscriptionMetadata
{
public SubscriptionMetadata(Type consumer)
{
if(!typeof(IConsumer).IsAssignableFrom(consumer))
{
string message = string.Format(
"{0} does not implement {1}",
typeof(IConsumer).Name,
consumer.Name);
throw new ArgumentOutOfRangeException("consumer", message);
}
this.ConsumerType = consumer;
}
public Type ConsumerType { get; private set; }
}
Registration of Metadata
Now this can be used like this in a Ninject module:
Bind<SubscriptionMetadata>()
.ToConstant(new SubscriptionMetadata(typeof(FooConsumer));
If you're going to use it a lot i'd recommend writing an extension method:
public static class SubscriptionBindingExtensions
{
public static void BindConsumer<T>(this IBindingRoot bindingRoot)
where T : IConsumer
{
Bind<SubscriptionMetadata>()
.ToConstant(new SubscriptionMetadata(typeof(T));
}
}
and usage (#Module):
BindConsumer<FooConsumer>();
IServiceBus creation
Now you would adapt the IServiceBus creation as follows:
var kernel = new StandardKernel();
// 2nd Step left out: load all IModule`s ..
var bus = ServiceBusFactory.New(sbc =>
{
//other configuration options
foreach(var metadata in kernel.GetAll<SubscriptionMetadata>())
{
sbc.Subscribe(subs =>
{
subs.Consumer(metadata.ConsumerType, kernel)
});
}
});
Convention based binding of Consumers
It can also be used in conjunction with conventions by leveraging the IBindingCreator interface. If you wish, i can post an example.

Domain model validation, inheritance and testability

The Situation
I'm building a C# web application and I want to model my app configuration as an explicit dependency to be handed in through the constructor of a service instead of relying on System.Configuration.ConfigurationManager directly in each of the classes. This did bite my quite often in the past so I want the dependency to be explicit so that the next maintainer of the project (probably future me) doesn't have to guess where my services get their configuration settings - on top of that it is more TDD friendly. Furthermore I'm currently reading Eric Evan's Domain Driven Design and I really want to embrace his DDD approach.
I started modeling the configuration class and corresponding value objects to avoid Primitive Obsession but I hit some bumps on the way and I'm not sure how to handle them appropriately. Here is my current approach:
// Role interface that can be requested via constructor injection
interface IAppConnectionStringsConfig
{
OleDbConnectionString AuthenticationConnectionString { get; }
}
// A base class for handling common functionality like
// parsing comma separated lists or default values
class abstract AppConfigBase
{
protected string GetStringAppSetting(string key)
{
// Get the appropriate string or a default value from
// System.Configuration.ConfigurationManager
return theSettingFromSomeConfigSource;
}
}
// A value object for OLEDB connection strings that also has a
// convenient implicit conversion to string
class OleDbConnectionString
{
public readonly string Value;
public OleDbConnectionString(string connectionString)
{
Contract.Requires(connectionString != null);
this.VerifyStructure(connectionString);
this.Value = connectionString;
}
private void VerifyStructure(string text)
{
Contract.Requires(text != null);
// Verify that the given string fulfills the special
// needs of an OleDbConnectionString (including Provider=...)
if (!/* isValidOleDbConnectionString */)
{
throw new FormatException();
}
}
public implicit operator string(ConnectionString conn)
{
return conn.Value;
}
}
// The actual app config that implements our role interface
class AppConfig : AppConfigBase, IAppConnectionStringsConfig
{
public OleDbConnectionString AuthenticationConnectionString
{
get
{
return new OleDbConnectionString(this.GetStringAppSetting("authconn"));
}
}
}
The Problem
I know that constructor logic should be minimal and that is not a good idea to call virtual methods from the constructor. My questions are as follows:
1) Where should I put the validation logic for the OleDbConnectionString? I really want to prevent the creation of value objects in an invalid state - that's excrutiatingly usefull at a day to day basis :-)
I have the feeling that this is domain logic that should be owned by the class itself but on the other hand the constructor should do as little as possible - wouldn't the string parsing be too much or is this ok?
I could create a validator but I most certainly had to hand that in through the constructor for being able to test that thing properly and then I have to wire that manually or use a factory (I'm definitely not using a Service Locator). On top of that the validation now would be hidden in a separate service; I wouldn't have the temporal coupling since the constructor requires the validator but still that doesn't look right.
2) I wonder if it would be appropriate to make DDD value objects structs? They - like the name suggests - represent a single value and this value is immutable. But they would contain business logic in the form of validation
3) Is it OK to use a property for retrieving the connection string? It could throw an exception if the format for the string isn't valid. Furthermore it's perfectly possible that the implementation will be changed from reading from an xml config file to querying a database.
4) Any other comments on the design are welcome!
As a side note, I'm already using Code Contracts and there is a way to specify object invariants but I don't know whether this is really a good idea since these contracts are opt-in and in the case that they are inactive the invariants are no longer actively protected. I'm not sure about this, for development purposes to catch errors early it might be fine but for production it seems off.
Thx!
I never really thought about general settings as a DDD problem - are you modelling a domain that is about settings and how they are saved, or just allowing settings to be saved and used in an application that has some inner parts modeled as DDD?
You can split this out by separating concerns of getting settings away from the things that use the settings.
Is it OK to use a property for retrieving the connection string? It could throw an exception if the format for the string isn't valid.
I don't think its a good idea to throw an exception if a setting cannot be retrieved so you can return defaults which would allow the program to continue.
But also remember that the default returned value (i.e. a password, or network address) will probably cause the thing that depends on that setting to throw an exception.
I would look at allowing the construction to happen OK but when coming to use the service i.e. Sender.Send() or Sender.Connect() is when you would throw an exception.
Where should I put the validation logic for the OleDbConnectionString? I really want to prevent the creation of value objects in an invalid state
I create objects that can never return an invalid result, but they do return a default settings value:
public class ApplicationSettings : IIdentityAppSettings, IEventStoreSettings
{
/* snip */
static readonly object KeyLock = new object();
public byte[] StsSigningKey
{
get
{
byte[] key = null;
lock (KeyLock)
{
var configManager = WebConfigurationManager.OpenWebConfiguration("/");
var configElement = configManager.AppSettings.Settings["StsSigningKey"];
if (configElement == null)
{
key = CryptoRandom.CreateRandomKey(32);
configManager.AppSettings.Settings.Add("StsSigningKey", Convert.ToBase64String(key));
configManager.Save(ConfigurationSaveMode.Modified); // save to config file
}
else
{
key = Convert.FromBase64String(configElement.Value);
}
}
return key;
}
/* snip */
}
}
What I generally do
I have the settings interfaces for each bounded context defined in the domain model as part of the infrastructure - this allows a number of known interfaces which I can reference and trust to provide some form of settings.
ApplicationSettings is defined in the code that hosts my bounded context(s) be it a Console app or WebAPI or MVC etc, I may have multiple bounded contexts hosted under the same process, or may split them out as separate processes, either way it is the job of the hosting application to provide the relevant application settings and wiring can be done via the IoC container.
public class ApplicationSettings : IIdentityAppSettings, IEventStoreSettings
{
// implement interfaces here
}
public interface IEventStoreSettings
{
string EventStoreUsername { get; }
string EventStorePassword { get; }
string EventStoreAddress { get; }
int EventStorePort { get; }
}
public interface IIdentityAppSettings
{
byte[] StsSigningKey { get; }
}
I use SimpleInjector .NET IoC container to wire up my applications. I then register all the application interfaces with SimpleInjector (so i can query based on any of the application interfaces and have the settings class object returned):
resolver.RegisterAsImplementedInterfaces<ApplicationSettings>();
I can then have the specific interface injected in, an example is a command handler that uses an IRepository, which in turn the EventStoreRepository (which is wired up as an implementation of IRepository) uses IEventStoreSettings (which is wired up as the ApplicationSettings instance):
public class HandleUserStats : ICommandHandler<UserStats>
{
protected IRepository repository;
public HandleUserStats(IRepository repository)
{
this.repository = repository;
}
public void Handle(UserStats stats)
{
// do something
}
}
And my repository would in turn be wired up:
public class EventStoreRepository : IRepository
{
IEventStoreSettings eventStoreSettings;
public EventStoreRepository(IEventStoreSettings eventStoreSettings)
{
this.eventStoreSettings = eventStoreSettings;
}
public void Write(object obj)
{
// just some mockup code to show how to access setting
var eventStoreClient = new EventStoreClient(
this.eventStoreSettings.EventStoreUsername,
this.eventStoreSettings.EventStorePassword,
this.eventStoreSettings.EventStoreAddress,
this.eventStoreSettings.Port
);
// if ever there was an exception either during setup of the connection, or
// exception (if you don't return a default value) accessing settings, it
// could be caught and bubbled up as an InfrastructureException
// now do something with the event store! ....
}
}
I allow settings to be passed in from some external source (like a WCF receive, or MVC controller action) and wired up by getting resolver.GetInstance<CommandHandler<UserStats>>(); which wires up all the settings for me all the way down to the implementation level.

Injecting dependencies into AuthorizeAttribute in a class library

I've run into an interesting design issue with a class library I am writing. I have a custom implementation of the AuthorizeAttribute that I want clients to be able to use like this:
[Protected("permission_name")]
In the above code, PermissionAttribute inherits from AuthorizeAttribute and uses a local default (DefaultContext created using HttpContext).
Behind the scenes, the attribute uses a SecurityService to check users, roles and permissions against (the SecurityService itself uses a client-provided persistence service that they can wire up in the composition root of their app).
So my attributes need a reference to the SecurityService to function. Since Attribute constructors can only have compile-time constants, I cannot use constructor injection.
I don't want to force my clients to use a DI framework - they should be able to discover and wire up the necessary dependencies in their composition root without using an IoC library, if they so choose.
Here are my options:
Have the library use a singleton SecurityService.
Use property injection, which would work but
it would make the dependency seem optional, which it is not and
I don't know where I can do property injection in an MVC app on an authorize attribute.
A possible solution to 2. above is to do set an instance of SecurityService as a static property on the attribute at application startup and use a guard clause to prevent it from being set more than once, like this:
class ProtectedAttribute : ...
{
private static ISecurityService _SecurityService ;
public static ISecurityService SecurityService
{
get
{
return _SecurityService ;
}
set
{
if (_SecurityService != null)
throw new InvalidOperationException("You can only set the SecurityService once per lifetime of this app.") ;
_SecurityService = value ;
}
}
}
The SecurityService could be an abstract service facade so that it can be extended/replaced by a different implementation.
Is there a better way to solve this problem?
UPDATE: Adding some code to show how I am going to do it:
Add a public property on the attribute that returns the permission name:
public class ProtectedAttribute : ...
{
private string _Permission ;
public string Permission { get { return _Permission ; } /*...*/ }
public ProtectedAttribute(string permission) { /*...*/ }
}
Setup an authorization filter and configure dependency via Ninject (if using Ninject):
using Ninject.Web.Mvc.FilterBindingSyntax;
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// mySecurityService instance below can have a singleton lifetime - perfect!
this.BindFilter<MyAuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<ProtectedAttribute>()
.WithConstructorArgument("securityService", mySecurityService)
.WithConstructorArgumentFromActionAttribute<ProtectedAttribute>("permission", p => p.PermissionName) ;
}
}
Ohhh it's...beautiful sniffle
With ASP.NET MVC 3 you could use constructor injection with action filters thanks to the new IFilterProvider. This way you no longer need to decorate your controller actions with action filters. You could apply them thanks to this interface and using a marker attribute.
And if you don't wanna bother implementing it manually you could always use an existing DI framework such as Ninject which provides a fluent way to define action filter dependencies.
My applications inherit from a base Application class that exposes the IOC container.
public interface IInjectableApplication
{
IUnityContainer Container { get; }
}
Then I have a base attribute class, which is aware of this
public abstract IocAwareActionFilterAttribute : ActionFilterAttribute{
protected T ResolveItem<T>(ResultExecutedContext context)
{
var app = context.HttpContext.ApplicationInstance as IInjectableApplication;
if (app == null) { throw new NullReferenceException("Application is not IInjectable."); }
T c = (T)app.Container.Resolve(typeof(T));
if (c == null) { throw new NullReferenceException(string.Format("Could not find injected {0}.", typeof(T).FullName)); }
return c;
}
}
While this is not true Injection, since Attributes aren't constructed 'normally', this provides a similar behavior. No reason it should not be adaptable to other IOCs

Microsoft Unity 2, how to register the following?

Right now we have a dll file that contains all the database calls and i can't change it. However i need to call i from my Mvc 3 project. The process to call it is simple, i use the following:
ManageProvider.GetProxy<T>(ident);
T is an interface that i want to get the class back from (its like an IoC of its own) and ident is the user identification class. So by calling
var classReturned = ManageProvider.GetProxy<ICommunity>(new UserIden{ Email = "test#test.com" });
I would get a class back with all the community functions.
Now i want to implement Unity in my Mvc 3 project. The question is, can i somehow add these calls to the dll file through unity?
I want to resolve the call by using:
var classReturned = myContainer.Resolve<ICommunity>(new UserIden{ Email = "test#test.com" });
How can i register this in Unity (or is it even possible) ?
Update:
1) Is it better to call the methods with the email/user ident instead of defining a Dependency property? (ex below)
2) There is a bout 20 or so interfaces in the dll file right now. Should i add them all to the same reposatory? (ex below)
public class ProxyWrapper : IDllRepository
{
[Dependency]
public UserIdent UserIdent { get; set; }
public ICommunity GetCommunity()
{
return ManageProvider.GetProxy<ICommunity>(UserIdent);
}
public IDesktop GetDesktop()
{
return ManageProvider.GetProxy<IDesktop>(UserIdent);
}
}
public interface IDllRepository
{
ICommunity GetCommunity();
IDesktop GetDesktop();
}
Whats the best way and how would i call it from my code?
Does the [Dependency] attribute also fall into the Service Locator anti pattern?
Update 23.05.11
1) Yes, something like that. They contain all the logic that is provided to all the projects that includes the dll file.
Regarding the ManagerProvider. It accepts an interface and returns the class that is mapped to this interface. So for the community, the interface looks like this (removed a lot of calls to keep it short, there is also posts, comments, community create/update etc):
List<CommunityThread> GetThreads(int pStartRowIndex, int pMaximumRows, string pOrderBy, string pSearchExpression);
Guid? CreateThread(string pTitle, string pDescription, string pPostContent);
bool DeleteThread(Guid pThreadId);
List<CommunityThread> GetCommunityUserThreads(Guid pCommunityUserId);
2) What i can't update is how the ManageProvider.GetProxy works. The GetProxy is a class in the dll file that is hardcoded. Here is the part for the community. The class does the same for all the other interfaces as well, if typeof(interface) ... return class.
private static IManageProxy GetProxyForInterface<T>(UserIdent pIdent)
{
....
if (typeof(T).Equals(typeof(ICommunity)))
return new PCommunity();
....
}
3) Once registered using this new wrapper class, i can call it through the following code (MvcUnityContainer is a static class that only has a property called Container):
var c = MvcUnityContainer.Container.Resolve<IBackendRepository>(new PropertyOverride("UserIdent",
new UserIdent()));
Global.asax
IUnityContainer container = InitContainer();
MvcUnityContainer.Container = container;
DependencyResolver.SetResolver(new UnityMvcResolver(container));
The question is, do i need the static class MvcUnityContainer? Is it possible to configure the DependecyResolver to do that for me? Something like (problem is that it doesn't accept the override parameter):
var c = DependencyResolver.Current.GetService<IBackendRepository>(new PropertyOverride("UserIdent", new UserIdent()));
I think you need to hide the creation behind another abstraction, for instance:
public interface ICommunityRepository
{
ICommunity GetByEmailAddress(string address);
}
public class ManageProviderCommunityRepository
: ICommunityRepository
{
public ICommunity GetByEmailAddress(string address)
{
var id = new UserIden { Email = address };
return ManageProvider.GetProxy<ICommunity>(id);
}
}
This will hide both the ManageProvider and the UserIden behind this abstraction, and allows you to replace it later on with something more useful and makes testing easier.
Registration now is very easy:
RegisterType<ICommunityRepository, ManageProviderCommunityRepository>();
Instead of calling myContainer.Resolve (as you do in your example), inject the dependencies in your classes. This prevents you from using the Service Locator anti-pattern.
Perhaps you could do something like this, using the InjectionFactory:
myContainer.RegisterType<ICommunity>(
new InjectionFactory(c => ManageProvider.GetProxy<ICommunity>(new UserIden {Email = "test#test.com"})));
var classReturned = myContainer.Resolve<ICommunity>();
... Though you wouldn't be able to pass the UserIden as a parameter to the Resolve call, so I'm not sure if this is what you want.
To register all the public classes of the assembly you could perhaps iterate over Assembly.GetTypes() and register them in the same way?

Categories

Resources