The UserService constructor has two parameters, a IUnitOfWork and a IUserRepository:
public UserService(IUnitOfWork unitofWork, IUserRepository userRepository)
{ ... }
I am using named registrations to differentiate between multiple instances of IUnitOfWork, so when registering the UserService with the Unity container, I need to explicitly specify the parameters using an InjectionConstructor:
container.RegisterType<IUserService, UserService>(
new InjectionConstructor(
new ResolvedParameter<IUnitOfWork>("someContext"),
new ResolvedParameter<IUserRepository>()
)
);
Is it possible for new ResolvedParameter<IUserRepository>() to be omitted? I would like Unity to implicitly deduce this parameter since there is no need for a named registration. The code would look like this:
container.RegisterType<IUserService, UserService>(
new InjectionConstructor(
new ResolvedParameter<IUnitOfWork>("someContext")
)
);
This would be done is any case when I don't need to use the InjectionConstructor.
Based on InjectionConstructor, I came up with this RequiredInjectionConstructor. It allows you to specify any set of arguments and it will attempt to find a constructor which is required to have (at a minimum) the passed set of injection parameters. If there are multiple constructors that meet this criteria, it chooses the constructor with the least number of parameters. The remaining constructor parameters are assumed to be unnamed resolved parameters.
I haven't performed a full suite of unit tests on it yet, so let me know if you encounter any issues.
/// <summary>
/// A class that holds the collection of minimum required
/// parameters for a constructor, so that the container can
/// be configured to call this constructor.
/// </summary>
public class RequiredInjectionConstructor : InjectionMember
{
private readonly List<InjectionParameterValue> _requiredParameterValues;
/// <summary>
/// Create a new instance of <see cref="RequiredInjectionConstructor"/> that looks
/// for a constructor with a minimum of the given required set of parameters.
/// </summary>
/// <param name="requiredParameterValues">The values for the parameters, that will
/// be converted to <see cref="InjectionParameterValue"/> objects.</param>
public RequiredInjectionConstructor(params object[] requiredParameterValues)
{
_requiredParameterValues = InjectionParameterValue.ToParameters(requiredParameterValues).ToList();
}
/// <summary>
/// Add policies to the <paramref name="policies"/> to configure the
/// container to call this constructor with the required parameter values.
/// </summary>
/// <param name="serviceType">Interface registered, ignored in this implementation.</param>
/// <param name="implementationType">Type to register.</param>
/// <param name="name">Name used to resolve the type object.</param>
/// <param name="policies">Policy list to add policies to.</param>
public override void AddPolicies(Type serviceType, Type implementationType, string name, IPolicyList policies)
{
ConstructorInfo ctor = FindConstructor(implementationType, _requiredParameterValues);
IEnumerable<InjectionParameterValue> selectedConstructorParameterValues = GetSelectedConstructorParameterValues(ctor, _requiredParameterValues);
policies.Set<IConstructorSelectorPolicy>(
new SpecifiedConstructorSelectorPolicy(ctor, selectedConstructorParameterValues.ToArray()),
new NamedTypeBuildKey(implementationType, name));
}
private static ConstructorInfo FindConstructor(Type typeToCreate, IEnumerable<InjectionParameterValue> requiredInjectionParameters)
{
var typeToCreateReflector = new ReflectionHelper(typeToCreate);
var matchedConstructors = typeToCreateReflector.InstanceConstructors.
Where(ctor =>
{
var constructorParameterTypes = ctor.GetParameters().Select(info => info.ParameterType);
return requiredInjectionParameters.All(required => constructorParameterTypes.Any(required.MatchesType));
});
if (matchedConstructors.Any())
{
// Prefer the constructor that has the least number of arguments.
// Other preference models could be implemented here.
return matchedConstructors.OrderBy(ctor =>
ctor.GetParameters().Count()).
FirstOrDefault();
}
string signature = string.Join(", ", requiredInjectionParameters.Select(required => required.ParameterTypeName).ToArray());
throw new InvalidOperationException(
string.Format("Unable to find a constructor with the minimum required parameters. Type: {0}, RequiredParameters: {1}",
typeToCreate.FullName,
signature));
}
private static IEnumerable<InjectionParameterValue> GetSelectedConstructorParameterValues(ConstructorInfo ctor, IEnumerable<InjectionParameterValue> requiredInjectionParameters)
{
var injectionParameterValues = new List<InjectionParameterValue>();
foreach (var parameter in ctor.GetParameters())
{
var existingInjectionParameter = requiredInjectionParameters.FirstOrDefault(required => required.MatchesType(parameter.ParameterType));
injectionParameterValues.Add(existingInjectionParameter ?? new ResolvedParameter(parameter.ParameterType));
}
return injectionParameterValues;
}
}
Would you be willing to decorate your constructor with the DependencyAttribute from Unity? This solution is straight forward, built-in, and lets you pick and chose named dependency. But it does 'dirty' your constructor with Unity goo.
public UserService(
[Dependency("someContext")]IUnitOfWork unitofWork,
IUserRepository userRepository)
{ ... }
Another solution would be to write a custom BuilderStrategy and UnityContainerExtension. This could be done with a bit more work.
Related
I have an Action that consumes application/x-www-form-urlencoded:
[HttpPost("~/connect/token"), Consumes("application/x-www-form-urlencoded")]
public async Task<IActionResult> Exchange([FromBody]OpenIdConnectRequest request)
{
..
}
But Swashbuckle generates empty array for Consumes property. If I change it to application/json, consumes array is generated properly.
Is it a bug related to application/x-www-form-urlencoded or I need to configure Swashbuckle additionally to support this application type?
That 'consumes' is not catered for out-of-the-box for Swashbuckle, a custom extension is required like the ones in this part of #domaindrivendev's GitHub project
There are three steps:
Create Parameter Attribute
Create Extension
Add instruction to Swashbuckle to process the new extension
Add an attribute to the parameter in an Controller method
I'll add more instructions in my fork of the repo, but here is the code:
1. FromFormDataBodyAttribute.cs
using System;
using System.Collections.Generic;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Validation;
/// <summary>
/// FromFormDataBody Attribute
/// This attribute is used on action parameters to indicate
/// they come only from the content body of the incoming HttpRequestMessage.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
public sealed class FromFormDataBodyAttribute : ParameterBindingAttribute
{
/// <summary>
/// GetBinding
/// </summary>
/// <param name="parameter">HttpParameterDescriptor</param>
/// <returns>HttpParameterBinding</returns>
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
if (parameter == null)
throw new ArgumentNullException("parameter");
IEnumerable<MediaTypeFormatter> formatters = parameter.Configuration.Formatters;
IBodyModelValidator validator = parameter.Configuration.Services.GetBodyModelValidator();
return parameter.BindWithFormatter(formatters, validator);
}
}
2 AddUrlFormDataParams.cs
using Swashbuckle.Swagger;
using System.Linq;
using System.Web.Http.Description;
/// <summary>
/// Add UrlEncoded form data support for Controller Actions that have FromFormDataBody attribute in a parameter
/// usage: c.OperationFilter<AddUrlFormDataParams>();
/// </summary>
public class AddUrlFormDataParams : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var fromBodyAttributes = apiDescription.ActionDescriptor.GetParameters()
.Where(param => param.GetCustomAttributes<FromFormDataBodyAttribute>().Any())
.ToArray();
if (fromBodyAttributes.Any())
operation.consumes.Add("application/x-www-form-urlencoded");
foreach (var headerParam in fromBodyAttributes)
{
if (operation.parameters != null)
{
// Select the capitalized parameter names
var parameter = operation.parameters.Where(p => p.name == headerParam.ParameterName).FirstOrDefault();
if (parameter != null)
{
parameter.#in = "formData";//NB. ONLY for this 'complex' object example, as it will be passed as body JSON.
//TODO add logic to change to "query" for string/int etc. as they are passed via query string.
}
}
}
}
}
3 Update Swagger.config
//Add UrlEncoded form data support for Controller Actions that have FromBody attribute in a parameter
c.OperationFilter<AddUrlFormDataParams>();
4. Add an attribute to the parameter in an Controller method
[FromFormDataBody]OpenIdConnectRequest request
I have a section in appsettings.json which contains a list of libraries and their dependencies, and how to configure them in different execution environments.I'd like to be able to validate that the library collection includes all the dependencies.
That's easy enough to do with a little recursion. But I can't figure out how to override the configuration binding process so that I can do the validation.
The only way I've come up with is to create a raw collection of the libraries, based on appconfig.json, and then create a service which validates the collection and makes it available. Something like:
public class RawLibraries : List<Library>
{
}
public class LibraryResolver
{
public LibraryResolver( IOptions<RawLibraries> rawLibs, ILogger logger )
{
// validate rawLibs and log errors
}
// ...implementation
}
services.Configure<RawLibraries>(Configuration.GetSection("Libraries"));
services.AddSingleton<LibraryResolver, LibraryResolver>();
But this seems convoluted. Thoughts on a better approach?
Why not to follow the authors and write your own extension method with additional validation?
Take a look here. This is the source code of services.Configure<> method:
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods for adding options services to the DI container.
/// </summary>
public static class OptionsServiceCollectionExtensions
{
...
/// <summary>
/// Registers an action used to configure a particular type of options.
/// </summary>
/// <typeparam name="TOptions">The options type to be configured.</typeparam>
/// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the services to.</param>
/// <param name="configureOptions">The action used to configure the options.</param>
/// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> so that additional calls can be chained.</returns>
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, Action<TOptions> configureOptions) where TOptions : class
{
if (services == null)
throw new ArgumentNullException("services");
if (configureOptions == null)
throw new ArgumentNullException("configureOptions");
services.AddSingleton<IConfigureOptions<TOptions>>((IConfigureOptions<TOptions>) new ConfigureOptions<TOptions>(configureOptions));
return services;
}
}
}
As you can see Configure<TOptions> method is an extension method. Simply write your own let say ConfigureAndValidate<TOptions>() extension method which will do proper validation before services.AddSingleton... line.
I am developing an application and I started to use as my base some code from an example by John Papa. Looking on the web I found this same code and it appears in an answer to a question on
Stackoverflow. Here is the question:
How to de-attach an entity from a Context in Entity Framework?
It's in the answer that was given by: SynerCoder
One part of the answer suggests the following class that is used to provide a repository from a dictionary of cached repositories. Can someone help me out and tell me is there really
an advantage in doing this. I understand the code but can't see the point of keeping repositories in a dictionary. Would it not be the case that every new web request would see an
empty dictionary and have to get / make a new repository anyway.
Data/Helpers/IRepositoryProvider.cs
using System;
using System.Collections.Generic;
using System.Data.Entity;
using Data.Contracts;
namespace Data.Helpers
{
/// <summary>
/// A maker of Repositories.
/// </summary>
/// <remarks>
/// An instance of this class contains repository factory functions for different types.
/// Each factory function takes an EF <see cref="DbContext"/> and returns
/// a repository bound to that DbContext.
/// <para>
/// Designed to be a "Singleton", configured at web application start with
/// all of the factory functions needed to create any type of repository.
/// Should be thread-safe to use because it is configured at app start,
/// before any request for a factory, and should be immutable thereafter.
/// </para>
/// </remarks>
public class RepositoryFactories
{
/// <summary>
/// Return the runtime repository factory functions,
/// each one is a factory for a repository of a particular type.
/// </summary>
/// <remarks>
/// MODIFY THIS METHOD TO ADD CUSTOM FACTORY FUNCTIONS
/// </remarks>
private IDictionary<Type, Func<DbContext, object>> GetFactories()
{
return new Dictionary<Type, Func<DbContext, object>>
{
//If you have an custom implementation of an IRepository<T>
//{typeof(IArticleRepository), dbContext => new ArticleRepository(dbContext)}
};
}
/// <summary>
/// Constructor that initializes with runtime repository factories
/// </summary>
public RepositoryFactories()
{
_repositoryFactories = GetFactories();
}
/// <summary>
/// Constructor that initializes with an arbitrary collection of factories
/// </summary>
/// <param name="factories">
/// The repository factory functions for this instance.
/// </param>
/// <remarks>
/// This ctor is primarily useful for testing this class
/// </remarks>
public RepositoryFactories(IDictionary<Type, Func<DbContext, object>> factories)
{
_repositoryFactories = factories;
}
/// <summary>
/// Get the repository factory function for the type.
/// </summary>
/// <typeparam name="T">Type serving as the repository factory lookup key.</typeparam>
/// <returns>The repository function if found, else null.</returns>
/// <remarks>
/// The type parameter, T, is typically the repository type
/// but could be any type (e.g., an entity type)
/// </remarks>
public Func<DbContext, object> GetRepositoryFactory<T>()
{
Func<DbContext, object> factory;
_repositoryFactories.TryGetValue(typeof(T), out factory);
return factory;
}
/// <summary>
/// Get the factory for <see cref="IRepository{T}"/> where T is an entity type.
/// </summary>
/// <typeparam name="T">The root type of the repository, typically an entity type.</typeparam>
/// <returns>
/// A factory that creates the <see cref="IRepository{T}"/>, given an EF <see cref="DbContext"/>.
/// </returns>
/// <remarks>
/// Looks first for a custom factory in <see cref="_repositoryFactories"/>.
/// If not, falls back to the <see cref="DefaultEntityRepositoryFactory{T}"/>.
/// You can substitute an alternative factory for the default one by adding
/// a repository factory for type "T" to <see cref="_repositoryFactories"/>.
/// </remarks>
public Func<DbContext, object> GetRepositoryFactoryForEntityType<T>() where T : class
{
return GetRepositoryFactory<T>() ?? DefaultEntityRepositoryFactory<T>();
}
/// <summary>
/// Default factory for a <see cref="IRepository{T}"/> where T is an entity.
/// </summary>
/// <typeparam name="T">Type of the repository's root entity</typeparam>
protected virtual Func<DbContext, object> DefaultEntityRepositoryFactory<T>() where T : class
{
return dbContext => new EFRepository<T>(dbContext);
}
/// <summary>
/// Get the dictionary of repository factory functions.
/// </summary>
/// <remarks>
/// A dictionary key is a System.Type, typically a repository type.
/// A value is a repository factory function
/// that takes a <see cref="DbContext"/> argument and returns
/// a repository object. Caller must know how to cast it.
/// </remarks>
private readonly IDictionary<Type, Func<DbContext, object>> _repositoryFactories;
}
}
Here's the code that calls the factory:
using System;
using Data.Contracts;
using Data.Helpers;
using Models;
namespace Data
{
/// <summary>
/// The "Unit of Work"
/// 1) decouples the repos from the controllers
/// 2) decouples the DbContext and EF from the controllers
/// 3) manages the UoW
/// </summary>
/// <remarks>
/// This class implements the "Unit of Work" pattern in which
/// the "UoW" serves as a facade for querying and saving to the database.
/// Querying is delegated to "repositories".
/// Each repository serves as a container dedicated to a particular
/// root entity type such as a <see cref="Url"/>.
/// A repository typically exposes "Get" methods for querying and
/// will offer add, update, and delete methods if those features are supported.
/// The repositories rely on their parent UoW to provide the interface to the
/// data layer (which is the EF DbContext in this example).
/// </remarks>
public class UnitOfWork : IUnitOfWork, IDisposable
{
public UnitOfWork(IRepositoryProvider repositoryProvider)
{
CreateDbContext();
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
// Repositories
public IRepository<Event> Events { get { return GetStandardRepo<Event>(); } }
public IRepository<Candidate> Candidates { get { return GetStandardRepo<Candidate>(); } }
/// <summary>
/// Save pending changes to the database
/// </summary>
public void Commit()
{
//System.Diagnostics.Debug.WriteLine("Committed");
DbContext.SaveChanges();
}
protected void CreateDbContext()
{
DbContext = new UnicornsContext();
// Do NOT enable proxied entities, else serialization fails
DbContext.Configuration.ProxyCreationEnabled = false;
// Load navigation properties explicitly (avoid serialization trouble)
DbContext.Configuration.LazyLoadingEnabled = false;
// Because Web API will perform validation, I don't need/want EF to do so
DbContext.Configuration.ValidateOnSaveEnabled = false;
}
protected IRepositoryProvider RepositoryProvider { get; set; }
private IRepository<T> GetStandardRepo<T>() where T : class
{
return RepositoryProvider.GetRepositoryForEntityType<T>();
}
private T GetRepo<T>() where T : class
{
return RepositoryProvider.GetRepository<T>();
}
private UnicornsContext DbContext { get; set; }
#region IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (DbContext != null)
{
DbContext.Dispose();
}
}
}
#endregion
}
}
It seems to me that the factory makes things more complicated that they need be. Am I correct and should I do this a simpler way such as with something like:
private IRepository<xx> = new GenericRepository<xx>(dbContext);
One more point. In my application I am using Unity. So would it be even easier to just specify the needed repositories in the constructor and have Unity create the repositories for me. If I did this then is there a way I could pass around the dbContext so it could be used by Unity when creating the repository? Has anyone used Unity to create repositories like this?
OK. Here's my best shot:
The point of keeping repositories in a cache is to ensure that the repository is only initiated once per request. The repository cache is in the RepositoryProvider class and is exposed to the UnitOfWork by the GetRepositoryForEntityType method. So the advantage is that the unit of work is not concerned with caching or creation of repositories.
The RepositoryProvider class is instantiated once per unit of work. (NB - it is desirable to create the repositories new for every request). The RepositoryProvider keeps the repositories in a dictionary using the type as a key. This is fine when using the generic repository base which has a Type parameter. But what if you have created a custom repository? In this example the creation of repositories by type is handed off to the RepositoryFactories class via the MakeRepository method. The advantage is that creating repositories is separated from caching.
The RepositoryFactories class knows when to make a custom repository because it contains a dictionary that uses Type as a key and a function as a value. The function is the constructor for a custom repository. If there's a value in the dictionary then use that constructor otherwise just use the generic base constructor.
All this means that as you add entities you do not have to modify any of these classes unless you create a custom repository. And when you do that all you have to do is add an entry to the dictionary in RepositoryFactories
I'm trying develop a custom control for a WinRT/Metro application.
It has a dependency property and I would like to be able to set its value within the custom control. However, using SetValue breaks any bindings that consumers of the control may have created.
None of the solutions I've found (e.g. SetCurrentValue) seem to apply to WinRT/Metro. Is there a solution to this?
It sounds like a simple thing to do and - honestly! - I've tried to find a solution here and elsewhere. Any help would be greatly appreciated.
You can set the default value in PropertyMetadata (Dr. WPF's snippets to the rescue!).
#region IsAvailable
private static bool DefaultIsAvailable = false;
/// <summary>
/// IsAvailable Dependency Property
/// </summary>
public static readonly DependencyProperty IsAvailableProperty =
DependencyProperty.Register(
"IsAvailable",
typeof(bool),
typeof(CustomControl1),
new PropertyMetadata(DefaultIsAvailable, OnIsAvailableChanged));
/// <summary>
/// Gets or sets the IsAvailable property. This dependency property
/// indicates ....
/// </summary>
public bool IsAvailable
{
get { return (bool)GetValue(IsAvailableProperty); }
set { SetValue(IsAvailableProperty, value); }
}
/// <summary>
/// Handles changes to the IsAvailable property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnIsAvailableChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (CustomControl1)d;
bool oldIsAvailable = (bool)e.OldValue;
bool newIsAvailable = target.IsAvailable;
target.OnIsAvailableChanged(oldIsAvailable, newIsAvailable);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the IsAvailable property.
/// </summary>
/// <param name="oldIsAvailable">The old IsAvailable value</param>
/// <param name="newIsAvailable">The new IsAvailable value</param>
protected virtual void OnIsAvailableChanged(
bool oldIsAvailable, bool newIsAvailable)
{
}
#endregion
EDIT*
If you want to change the value - you can, but if you use a basic binding that is OneWay - i.e. - it takes the value from a binding source and sets it to the dependency property - the binding will stop working because source and target values won't be synchronized any more.
If you set Mode="TwoWay" - the binding source will be updated when the binding target (your control) modifies the dependency property, so the binding will remain valid and will continue working both ways.
Looked for a method on the MvcContrib.TestHelper.RouteTestingExtensions class named ShouldNotMap. There is ShouldBeIgnored, but I don't want to test an IgnoreRoute invocation. I want to test that a specific incoming route should not be mapped to any resource.
Is there a way to do this using MvcContrib TestHelper?
Update
Just tried this, and it seems to work. Is this the correct way?
"~/do/not/map/this".Route().ShouldBeNull();
I think you are looking for the following:
"~/do/not/map/this".ShouldBeIgnored();
Behind the scenes this asserts that the route is processed by StopRoutingHandler.
I was looking for the same thing. I ended up adding the following extension methods to implement ShouldBeNull and the even shorter ShouldNotMap:
In RouteTestingExtensions.cs:
/// <summary>
/// Verifies that no corresponding route is defined.
/// </summary>
/// <param name="relativeUrl"></param>
public static void ShouldNotMap(this string relativeUrl)
{
RouteData routeData = relativeUrl.Route();
routeData.ShouldBeNull(string.Format("URL '{0}' shouldn't map.", relativeUrl));
}
/// <summary>
/// Verifies that the <see cref="RouteData">routeData</see> is null.
/// </summary>
public static void ShouldNotMap(this RouteData routeData)
{
routeData.ShouldBeNull("URL should not map.");
}
In GeneralTestExtensions.cs :
///<summary>
/// Asserts that the object should be null.
///</summary>
///<param name="actual"></param>
///<param name="message"></param>
///<exception cref="AssertFailedException"></exception>
public static void ShouldBeNull(this object actual, string message)
{
if (actual != null)
{
throw new AssertFailedException(message);
}
}