EF4 CodeFirst CTP5 nvarchar(max) via attribute - entity-framework-4

Is there a way to create a custom attribute that will make EF CodeFirst use nvarchar(max) as datatype when assigned to a property of a poco class? I know this is possible via fluent api, but we would like to have all definitions within one place and thats the metadata class.
Fluent API:
modelBuilder.Entity<Event>().Property(p => p.TicketText).HasColumnType("nvarchar(max)");

public class NVarcharMaxAttribute : Attribute { }
public class NVarcharMaxAttributeConvention : AttributeConfigurationConvention<PropertyInfo, StringPropertyConfiguration, NVarcharMaxAttribute> {
public override void Apply(PropertyInfo memberInfo, StringPropertyConfiguration configuration, NVarcharMaxAttribute attribute) {
configuration.ColumnType = "nvarchar(max)";
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Conventions.Add<NVarcharMaxAttributeConvention>();
}

[System.ComponentModel.DataAnnotations.MaxLength]

Related

MVC 4 and Ninject: how do I add the client's user ID to my injected classes?

I'm using Ninject 3.0 to inject service layer data access classes into my controllers. I would like to add the client's domain user ID to these classes at runtime, but cannot figure out what approach I should use. Currently my NinjectModule looks something like this:
public class NinjectBindModule : NinjectModule
{
public override void Load()
{
Bind<ISomeRepo>().To<SomeRepo>();
}
}
My question, in two parts really is:
Should I use WithConstructorArgument to get the user ID into SomeRepo, or something else (property?). Can I even do this in the bind module, or does it have to be done at the kernel or controller level?
What method should I use to retrieve the client's domain user ID? I don't think I can use the Controller.User property at the kernel level or in the bind module, can I?
public class NinjectBindModule : NinjectModule
{
public override void Load()
{
Bind<ISomeRepo>().To<SomeRepo>();
Bind<IPrincipal>()
.ToMethod(ctx => HttpContext.Current.User)
.InRequestScope();
}
}
and then:
public class SomeRepo : ISomeRepo
{
private readonly IPrincipal _principal;
public SomeRepo(IPrincipal principal)
{
_principal = principal;
}
... some methods that will have access to the principal
}

Property injection in my custom attribute?

We are using StructureMap as container in my current project and all has been working well until we had to inject dependencies to a custom attribute we are using.
First, code for registering stuff in the container would look like this...
Container = new Container();
Registry = new Registry();
ServiceLocator = new StructureMapServiceLocator(Container);
Registry.For<IServiceLocator>().Use(ServiceLocator);
Registry.For<IHitCounter>().Add<HitCounter>();
Registry.For<IHitCountAttribute>().Use<HitCountAttribute>();
Registry.SetAllProperties(policy => policy.OfType<IHitCounter>());
Container.Configure(config => config.AddRegistry(Registry));
The kind of registering above do work for a normal class with setter injection (and constructor injection) but obviously not for an attribute class.
An attribute class could look like this...
public class HitCountAttribute : ActionFilterAttribute, IHitCountAttribute
{
public IHitCounter HitCounter { get; set; }
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
HitCounter.Count(HttpContext.Current.Request.Url.ToString());
base.OnResultExecuted(filterContext);
}
}
The interface look like this...
public interface IHitCountAttribute
{
IHitCounter HitCounter { get; set; }
void OnResultExecuted(ResultExecutedContext filterContext);
}
Is it even possible to inject dependencies to an attribute? As it is instantiated by the runtime...
Is there any other way to solve the problem with the dependencies?

MVC - Dynamic binding to multiple databases using Ninject?

I have a small MVC application that connects to a single MYSQL database. I had it setup with Ninject to bind the connectionString during the application startup. The code looked like this:
Global.asax.cs:
protected void Application_Start()
{
...
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
NinjectControllerFactory.cs:
public class NinjectControllerFactory : DefaultControllerFactory
{
...
private class EriskServices : NinjectModule
{
public override void Load()
{
// Bind all the Repositories
Bind<IRisksRepository>().To<MySql_RisksRepository>()
.WithConstructorArgument("connectionString",
ConfigurationManager.ConnectionStrings["dbcMain"]
.ConnectionString);
}
}
}
Today my requirements have changed and I have to now support multiple databases. I would like to have each database connection string defined in the web.config file, like how it was before. The user selects which database they want to connect to during the application login.
What would be the easiest way to bind my repositories after the login? I'm assuming I would need to code the database binding in the login controller.
I am kind of a newbie to Ninject so any examples would be much appreciated!
As always, Thanks for the time and help!
.
I would probably Bind the repository to a Ninject.Activation.IProvider, and then create your own provider that pulls the connectionString from Session
Bind<IRisksRepository>().ToProvider<SessionConnectionProvider>();
then...
public class SessionConnectionProvider : Ninject.Activation.IProvider
{
#region IProvider Members
public object Create( Ninject.Activation.IContext context )
{
// use however you're accessing session here
var conStr = session.ConnectionString;
return new MySql_RisksRepository( conStr );
}
public Type Type
{
get { return typeof( IRisksRepository ); }
}
#endregion
}

How to use custom injection attribute for properties when using StructureMap?

I would like to have my own injection attribute so that I am not coupling my code to a particular IOC framework. I have a custom injection attribute that my code uses to denote that a property should be injected.
public class CustomInjectAttribute : Attribute {}
Fictitious example below...
public class Robot : IRobot
{
[CustomInject]
public ILaser Zap { get; set; }
...
}
In Ninject, you can setup an injection Heuristic to find that attribute, and inject like;
public class NinjectInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
public new bool ShouldInject(MemberInfo member)
{
return member.IsDefined(typeof(CustomInjectAttribute), true);
}
}
and then register the heuristic with the kernel.
Kernel.Components.Get<ISelector>().InjectionHeuristics.Add(new NinjectInjectionHeuristic());
How would I go about achieving this with StructureMap. I know StructureMap has its own SetterProperties and attributes, but I'm looking for a way to decouple from that as you can with Ninject in the above example.
Use the SetAllProperties() method in your ObjectFactory or Container configuration. For example:
new Container(x =>
{
x.SetAllProperties(by =>
{
by.Matching(prop => prop.HasAttribute<CustomInjectAttribute>());
});
});
This makes use of a handy extension method (that should be in the BCL):
public static bool HasAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute
{
return provider.GetCustomAttributes(typeof (T), true).Any();
}

Entity Framework 4.0 . Entity Creation

We have two entities with identical columns but the entity name is different. Can i create 2 entity using the first entity instance ?
We tried doing .AddObject("Entity2 name",entityOneinstance) but it is failing.
Please suggest whether this is possible or any other approach.
Thanks in advance
Since the types of entities are different, your add operation will fall for sure.
You will need a mapper or (explicit/implicit) conversion operator between your entity types I think.
To make it clear, for the conversation solution, suppose you have Entity1 and Entity2 and both have properties, Property, Property_1, Property_2 and Property_3. I assume that you have default code generation strategy (not POCO or sth). Then you can add partial Entity2 and Entity1 classes with implicit conversion operatior, for example:
public partial class Entity2
{
public static implicit operator Entity2(Entity1 entity1)
{
return new Entity2()
{
Property = entity1.Property,
Property_1 = entity1.Property_1,
Property_2 = entity1.Property_2,
Property_3 = entity1.Property_3
};
}
}
So you can now do:
using (var provider = new Model1Container12())
{
Entity1 entity1 = new Entity1();
provider.AddObject(provider.Entity2Set.Name, entity1);
// or
provider.AddToEntity2Set(entity1);
}
The conversion will be made implicitly as you define in the conversion operator definition.
I don't know if Entity Framework itself has a solution for this situation but conversion seems like a solution for me. Or you can also use AutoMapper kind of thing. I don't have detailed information on that.
In EF4, ObjectSet was introduced, which is kinda nifty..
My approach would be using repository pattern...
First create an abstract base class..
public abstract class BaseRepository<T> where T : class
{
#region Members
protected IObjectSet<T> _objectSet;
#endregion
#region Ctor
public BaseRepository(ObjectContext context)
{
_objectSet = context.CreateObjectSet<T>();
}
#endregion
#region Methods
public void Add(T entity)
{
_objectSet.AddObject(entity);
}
public IEnumerable<T> GetAll()
{
return _objectSet;
}
#endregion
}
Then create a derived class for each tabel you need to access..
An example (interface and implemtation):
Producer is the tables POCO object.
Interface:
public interface IProducerRepository
{
Producer GetById(int id);
void Add(Producer entity);
IEnumerable<Producer> GetAll();
}
Implementation:
public class ProducerRepository : BaseRepository<Producer>, IProducerRepository
{
#region Ctor
public ProducerRepository(ObjectContext context) : base(context)
{
}
#endregion
#region Methods
public Producer GetById(int id)
{
return _objectSet.SingleOrDefault(e => e.Id == id);
}
#endregion
}
Hope this helps.. :-)

Resources