Using 'System.Lazy.LazyThreadSafetyMode' with MEF - thread-safety

I import many parts from different assemblies into my class like this:
[ImportMany(typeof(IServiceProvider))]
private IEnumerable<Lazy<IServiceProvider, IDictionary<string, object>>> ServiceProviders
{
get;
set;
}
After parts imported, Service providers are created on demand:
private IServiceProvider GetServiceProvider(String name)
{
foreach (var serviceProvider in ServiceProviders)
{
String currentName = (String)serviceProvider.Metadata["Name"];
if (currentName == name)
return serviceProvider.Value; // Many threads receive here and try to create new instance.
}
return null;
}
As I commented in above code, many threads try to get value of the lazy variable (create new instance of it, if not created yet) at the same time.
Lazy<T>has a constructor which allow to create instance (value) in a thread-safe manner, like this:
// Something here...
Dictionary<string, object> metadata = new Dictionary<string,object>();
metadata.Add("Name", "test");
Lazy<IServiceProvider, IDictionary<string, object>> serviceProvider = new Lazy<IServiceProvider, IDictionary<string, object>>(ServiceProviderValueFactory, metadata, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
// Now access to 'serviceProvider.Value' creates an instance (if not created yet) in a thread-safe manner.
private IServiceProvider ServiceProviderValueFactory()
{
// Create and return a new instance of 'IServiceProvider'.
}
MEF take cares of object creation when importing parts and I want to use the Lazy constructor which allows for thread-safe value creation but I don't know how.

When creating your CompositionContainer, pass isThreadSafe=true to the constructor.
Note that it's not safe to do any recomposition in a thread-safe container, so you shouldn't use catalogs that change, or CompositionBatch, or the AttributedModelServices.ComposeParts() extension method.

I'm not convinced this is something you can change. The Lazy<T, M> type is initialised through the ExportServices internal class, and cannot be overridden. If you subclassed ExportProvider the target GetExports or GetExportsCore that return Lazy<T, M> are not abstract or virtual so cannot be overridden.
In ExportServices, it is hard coded as:
return new Lazy<T, M>(..., LazyThreadSafetyMode.PublicationOnly);

Related

What is the expected LifeStyle of a Castle Windsor component activator?

I'm using Castle Windsor and DynamicProxy to implement persistence Lazy Loading from scratch (I know NHibernate could be an option etc.) I have implemented a custom component activator to always instantiate my business classes as proxies. I found that the default mixin proxies automatically created when using interceptors were not being used when class methods are called from inside the class itself, which was a problem. So I inherited DefaultComponentActivator and overriding CreateInstance() I'm calling CreateClassProxy() to get a proxy that inherits from the business class, which in that respect works fine.
Now I was expecting this 'ProxyComponentActivator' activator of mine to be instantiated by Castle only once, but a new instance is being created for each class type. Is that correct?
Current registration is like this:
public void Install(
IWindsorContainer container,
Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store) {
container.Register(
Classes
.FromAssemblyContaining(typeof(OneOfMyBusinessClasses))
.InNamespace(typeof(OneOfMyBusinessClasses).Namespace)
.WithService.DefaultInterfaces()
.Configure(reg => reg.Activator<ProxyComponentActivator>())
.LifestyleTransient(),
etc.
);
);
The activator implementation is the following:
public class ProxyComponentActivator : DefaultComponentActivator
{
protected Castle.DynamicProxy.ProxyGenerator ProxyGenerator { get; set; }
protected PersistenceInterceptor PersistenceInterceptor { get; set; }
public ProxyComponentActivator(ComponentModel model, Castle.MicroKernel.IKernelInternal kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction)
{
this.ProxyGenerator = kernel.Resolve<Castle.DynamicProxy.ProxyGenerator>();
this.PersistenceInterceptor = kernel.Resolve<PersistenceInterceptor>();
}
protected override object CreateInstance(CreationContext context, ConstructorCandidate constructor, object[] arguments) //, Type[] signature)
{
object instance;
Type implType = this.Model.Implementation;
ProxyGenerationOptions p = new ProxyGenerationOptions();
IPersistent ip = new Persistent();
p.AddMixinInstance(ip);
try
{
instance = this.ProxyGenerator.CreateClassProxy(implType, null, p, arguments, this.PersistenceInterceptor);
}
catch
{
throw new ComponentActivatorException("ComponentActivator: could not proxy " + implType.FullName, Model);
}
return instance;
}
}
I have also tried to register the activator like this, to no avail...
Component.For<ProxyComponentActivator>()
.ImplementedBy<ProxyComponentActivator>()
.LifestyleSingleton()
Thanks in advance for any help,
Luis
Every component in Windsor will get its own activator instance

Are there any problems with using a static property to return DbContext

I've been trying to implement a new MVC3 project with Entity Framework 4.1, which instantiates the dbContext on Application_BeginRequest, and disposes it on Application_EndRequest
protected virtual void Application_BeginRequest()
{
HttpContext.Current.Items["_EntityContext"] = new EntityContext();
}
protected virtual void Application_EndRequest()
{
var entityContext = HttpContext.Current.Items["_EntityContext"] as EntityContext;
if (entityContext != null)
entityContext.Dispose();
}
The EntityContext class is defined as follows:
public class EntityContext : MyEntities, IDisposable
{
**//should this be static?**
public static EntityContext Current
{
get { return HttpContext.Current.Items["_EntityContext"] as EntityContext; }
}
void IDisposable.Dispose()
{
Current.Dispose();
}
My question is, will defining my Current property as static cause any problems in a multi-user scenario?
Your lifespan on DbContext is WAY too long. You should be spinning up a bare minimum of one per request, and even better one per access to the database.
As insta pointed out, you should instance the context when you actually need it. There's no advantage making your context lifespan that long.
As a side-note, there's no need to call explicitly the Dispose method, since the .NET Garbage Collector will do that more efficiently for you.
You could instance the context per class, since you're using MVC, instance the context once per Controller.
public class MyTableObjectController : Controller
{
MyContext context = new MyContext();
public ActionResult Index()
{
var model = context.MyTableObjects;
return View(model);
}
}
I might ask, why are you trying to keep your context available between Begin and End request? Are you trying to avoid instancing it?

Create class that implements a particular design pattern with ReSharper

Design patters are a point of arguments between developers, but I use them very often. Even more, I use one of the most controversial of all common patterns - singleton.
Here is how I implement it in C#:
class MySingletonClass
{
private static volatile MySingletonClass _instance;
private static object syncRoot = new Object();
public static MySingletonClass Instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
if (_instance == null)
_instance = new MySingletonClass();
}
}
return _instance;
}
}
private MySingletonClass()
{
}
}
I want to be able to automatically create singleton classes while developing, with only entering a name for the class.
How can I implement this functionality with ReSharper? Can ReSharper pattern catalog be used for this?
Thank you.
You can create a Code Template for it (a File Template if you wish every singleton in a new file).
There are instructions on how to create a template from scratch and from existing code in the help files.

How can I load multiple controller factories and pass control on to the next one?

I've created a generic controller factory to load entities from the database by parsing out the url:
entity/products/123456.htm
However, I'd like to be able to load an actual controller if the entity is not found, or to override the default entity behavior if necessary by creating a physical controller, instead of a "virtual" one created by the URL pattern.
Right now, in global.asax.cs I'm doing:
ControllerBuilder.Current.SetControllerFactory(typeof(EntityControllerFactory));
How can I, either in EntityControllerFactory, or here in global.asax.cs, pass control on to another factory, in the event that I'd like MVC's default controller/action scheme to take over?
You could create a composite IControllerFactory implementation:
public class EntityControllerFactory : IControllerFactory {
private IControllerFactory defaultFactory = new DefaultControllerFactory();
public IController CreateController(RequestContext requestContext, string controllerName) {
if(needsCustomLogic) {
// do your custom logic here and return appropriate result
} else {
return defaultFactory.CreateController(requestContext, controllerName);
}
}
// same for the other methods on IControllerFactory
}
This works because by default the value of ControllerBuilder.Current.GetControllerFactory() is an instance of DefaultControllerFactory.
You might also consider making your factory more future-proof (in case a new version of MVC starts returning a different type from GetControllerFactory; unlikely but it could happen) by getting the default instance and passing it into your factory:
// in Global.asax
var defaultFactory = ControllerBuilder.Current.GetControllerFactory();
ControllerBuilder.Current.SetFactory(new EntityControllerFactory(defaultFactory));

asp.net MVC 2 - View Model / Model Validation - Is there a way to map validation attributes from model to ViewModel via AutoMapper? [duplicate]

I use AutoMapper to map my domain objects to my view models. I have metadata in my domain layer, that I would like to carry over to the view layer and into ModelMetadata. (This metadata is not UI logic, but provides necessary information to my views).
Right now, my solution is to use a separate MetadataProvider (independently of ASP.NET MVC), and use conventions to apply the relevant metadata to the ModelMetadata object via an AssociatedMetadataProvider. The problem with this approach is that I have to test for the same conventions when binding the ModelMetadata from the domain as I do with my AutoMapping, and it seems like there should be a way to make this more orthogonal. Can anyone recommend a better way to accomplish this?
I use the approach below to automatically copy data annotations from my entities to my view model. This ensures that things like StringLength and Required values are always the same for entity/viewmodel.
It works using the Automapper configuration, so works if the properties are named differently on the viewmodel as long as AutoMapper is setup correctly.
You need to create a custom ModelValidatorProvider and custom ModelMetadataProvider to get this to work. My memory on why is a little foggy, but I believe it's so both server and client side validation work, as well as any other formatting you do based on the metadata (eg an asterix next to required fields).
Note: I have simplified my code slightly as I added it below, so there may be a few small issues.
Metadata Provider
public class MetadataProvider : DataAnnotationsModelMetadataProvider
{
private IConfigurationProvider _mapper;
public MetadataProvider(IConfigurationProvider mapper)
{
_mapper = mapper;
}
protected override System.Web.Mvc.ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
//Grab attributes from the entity columns and copy them to the view model
var mappedAttributes = _mapper.GetMappedAttributes(containerType, propertyName, attributes);
return base.CreateMetadata(mappedAttributes, containerType, modelAccessor, modelType, propertyName);
}
}
Validator Provivder
public class ValidatorProvider : DataAnnotationsModelValidatorProvider
{
private IConfigurationProvider _mapper;
public ValidatorProvider(IConfigurationProvider mapper)
{
_mapper = mapper;
}
protected override System.Collections.Generic.IEnumerable<ModelValidator> GetValidators(System.Web.Mvc.ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
var mappedAttributes = _mapper.GetMappedAttributes(metadata.ContainerType, metadata.PropertyName, attributes);
return base.GetValidators(metadata, context, mappedAttributes);
}
}
Helper Method Referenced in above 2 classes
public static IEnumerable<Attribute> GetMappedAttributes(this IConfigurationProvider mapper, Type sourceType, string propertyName, IEnumerable<Attribute> existingAttributes)
{
if (sourceType != null)
{
foreach (var typeMap in mapper.GetAllTypeMaps().Where(i => i.SourceType == sourceType))
{
foreach (var propertyMap in typeMap.GetPropertyMaps())
{
if (propertyMap.IsIgnored() || propertyMap.SourceMember == null)
continue;
if (propertyMap.SourceMember.Name == propertyName)
{
foreach (ValidationAttribute attribute in propertyMap.DestinationProperty.GetCustomAttributes(typeof(ValidationAttribute), true))
{
if (!existingAttributes.Any(i => i.GetType() == attribute.GetType()))
yield return attribute;
}
}
}
}
}
if (existingAttributes != null)
{
foreach (var attribute in existingAttributes)
{
yield return attribute;
}
}
}
Other Notes
If you're using dependency injection, make sure your container isn't already replacing the built in metadata provider or validator provider. In my case I was using the Ninject.MVC3 package which bound one of them after creating the kernel, I then had to rebind it afterwards so my class was actually used. I was getting exceptions about Required only being allowed to be added once, took most of a day to track it down.
if your metadata are provided with attributes define the attributes in MetaDataTypes, then apply the same MetaDataType to both your domain class and to your viewmodels. You can define all MetaDataTypes in a separate dll that is reference by both layers. There are some issues with this approach if your ViewModel classes have not some properties that is used in the MetaDataType, but this can be fixed with a custom Provider(I have the code if youlike this approach).
Betty's solution is excellent for "inheriting" data annotations. I have extended this idea to also include validation provided by IValidatableObject.
public class MappedModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
private readonly IMapper _mapper;
public MappedModelValidatorProvider(IMapper mapper)
{
_mapper = mapper;
}
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
var mappedAttributes = _mapper.ConfigurationProvider.GetMappedAttributes(metadata.ContainerType, metadata.PropertyName, attributes);
foreach (var validator in base.GetValidators(metadata, context, mappedAttributes))
{
yield return validator;
}
foreach (var typeMap in _mapper.ConfigurationProvider.GetAllTypeMaps().Where(i => i.SourceType == metadata.ModelType))
{
if (typeof(IValidatableObject).IsAssignableFrom(typeMap.DestinationType))
{
var model = _mapper.Map(metadata.Model, typeMap.SourceType, typeMap.DestinationType);
var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeMap.DestinationType);
yield return new ValidatableObjectAdapter(modelMetadata, context);
}
}
}
}
Then in Global.asax.cs:
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new MappedModelValidatorProvider(Mapper.Instance));

Resources