How the binding are done with decorators using Ninject? - inversion-of-control

Based on this question : Should thoses kind of service go injected in a base class ? (versus static classes).
How the binding would be done with decorators using Ninject ? or any DIContainer ?
public class CachedLoggedRepository : IRepository
{
public IRepository repository { get; set; }
void Add();
}
public class CachedRepository : IRepository
{
public IRepository repository { get; set; }
void Add();
}
public class Repository : IRepository
{
void Add();
}

You have to use conditional bindings e.g
Bind<IRepository>().To<Repository>().WhenInjectedInto<CachedRopsitory>();
Bind<IRepository>().To<CachedRepository>().WhenInjectedInto<CachedLoggedRepository>();
Bind<IRepository>().To<CachedLoggedRepository>();

Related

EF Core entity configuration not applied in OnModelCreating

I have a simple (at the moment) context which uses some base classes like this:
public abstract class EntityBase
{
public int Id { get; set; }
}
public abstract class TranslatableEntityBase : EntityBase
{
public string TranslationKey { get; set; }
public TranslatableEntityBase(string translationKey) : base()
{
TranslationKey = translationKey;
}
}
public class Country : TranslatableEntityBase
{
public Country(string name, string code, string translationKey)
: base(translationKey)
{
Name = name;
Code = code;
}
public string Name { get; set; }
public string Code { get; set; }
}
The configurations also have base classes like this:
public abstract class EntityBaseConfiguration<T> : IEntityTypeConfiguration<T> where T : EntityBase
{
public virtual void Configure(EntityTypeBuilder<T> builder)
{
}
}
public abstract class TranslatableEntityBaseConfiguration<T> : EntityBaseConfiguration<T> where T : TranslatableEntityBase
{
// Hide parent method to provide overridable one to children
public new virtual void Configure(EntityTypeBuilder<T> builder)
{
base.Configure(builder);
builder.Property(e => e.TranslationKey)
.IsRequired()
.HasMaxLength(255);
}
}
public class CountryConfiguration : TranslatableEntityBaseConfiguration<Country>
{
public override void Configure(EntityTypeBuilder<Country> builder)
{
base.Configure(builder);
builder.Property(c => c.Name)
.IsRequired()
.HasMaxLength(255);
builder.Property(c => c.Code)
.IsRequired()
.HasMaxLength(3);
}
}
And my context is defined this way:
public class MyContext : DbContext
{
public MyContext(DbContextOptions options)
: base(options)
{
}
public DbSet<Country> Countries { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
}
}
When I run dotnet ef migrations add InitialMigration, it creates the migration however the configuration of the entity is not applied (no max length or required).
I already tried using modelBuilder.ApplyConfiguration(new CountryConfiguration()); directly but with the same results.
What am I missing ? Is it because of the inheritance ?
Thanks
Ok I found it.
I just needed to make TranslatableEntityBaseConfiguration<T> inherit IEntityTypeConfiguration<T>
public abstract class TranslatableEntityBaseConfiguration<T> : EntityBaseConfiguration<T>, IEntityTypeConfiguration<T> where T : TranslatableEntityBase
{
// Hide parent method to provide overridable one to children
public new virtual void Configure(EntityTypeBuilder<T> builder)
{
base.Configure(builder);
builder.Property(e => e.TranslationKey)
.IsRequired()
.HasMaxLength(255);
}
}
I don't really know why...
EDIT:
I found another cleaner way to do it, by removing new virtual from this class, and using override instead. Which doesn't prevent me to override in the final class (which I naively thought)

Entity Framework Map Model To Table

I have following method in my Project.
public IEnumerable<T> GetAll()
{
return _context.Set<T>().ToList();
}
Then my DbContext has this..
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Entity<Product>.ToTable("Product");
}
This works fine, as long as "Product" Model is within same project.
However, different clients will be consuming my DataAccess layer and they will be passing Models of different types. How can I tell EntityFramework to dynamically Bind a Model to a "Table" in SQL server.
I was able to resolve this problem by doing the following.
public class Repository<T> : DbContext, IRepository<T> where T : BaseModel
{
public DbContext _context { get; set; }
public DbSet<T> _dbSet { get; set; }
public Repository(string con)
: base(con)
{
}
public IEnumerable<T> GetAll()
{
return _dbSet;
}
public void Add(T entity)
{
_dbSet.Add(entity);
_context.SaveChanges();
}
}
Basicly the steps are...
A. Class must inherit DbContext.
A Generic Property for DbSet.
Now DbSet is a Generic Table, which you can use in your Generic Repoitory.

How to add relationship between tables in two different DbContext

I have two DbContext class and some Entities in them. I know this is not good idea to have more than one DbContext but i have to do a lot of works to change my code! so my question is what is the best scenario for add relationship between two Entities with different DbContext?
For example an one to many relationship between User Entity with IdentityDb Context and Comment Entity with SiteDbContext :
public class User : IdentityUser
{
public DateTime JoinDate { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this,DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class IdentityDb : IdentityDbContext<ApplicationUser>
{
public IdentityDb() : base("DefaultConnection", throwIfV1Schema: false)
{
}
public static IdentityDb Create()
{
return new IdentityDb();
}
}
public class Comment
{
public int CommentId { get; set; }
[Required]
[StringLength(900)]
public string CommentText { get; set; }
[DataType(DataType.Date)]
public DateTime CommentDate { get; set; }
}
public class SiteDb: DbContext
{
public SiteDb(): base("DefaultConnection")
{
}
public DbSet<Comment> Comments{ get; set; }
}
Short answer: Entity Framework currently doesn't support creating a query which uses more than one context.
For work around: Refer this.

Unity.MVC register autogenerated dbcontext from ef

I have an autogenerated dbcontext from EF. I've created a partial class of this autogenerated EF class so I can make it implement an interface so that I can pass that interface to my service that will use it. That'll get passed in via Unity.MVC DI framework. When I try to register this interface to the actual class I'm getting an error:
"There is no implicit reference conversion from ContactsEntities to IContactsEntities."
I'm not sure why I'm getting that or how to solve it.
EF Autogen file:
public partial class ContactsEntities : DbContext
{
public ContactsEntities()
: base("name=ContactsEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Contact> Contacts { get; set; }
}
My file:
public interface IContactsEntities
{
DbSet<Contact> Contacts { get; set; }
}
public partial class ContactsEntities : IContactsEntities
{
public virtual DbSet<Contact> Contacts { get; set; }
}
Unity registering that gives the error:
container.RegisterType<IContactsEntities, ContactsEntities>();

How to configure Domain Classes to use ObservableCollection using EF?

I have started using Entity Framework Code First modeling technique and have seen many examples of implementing one to many (1-N) relationship using DataAnnotation and FluentAPI but all examples are using ICollection while modeling domain classes. I have already used generic ObservableCollection in my domain classes and do not intent to change it.
Currently while specifying the configuration using FluentAPI, i am getting following error:
HasRequired(t => t.App)
.WithMany(t => t.EndPoints) // error here
.HasForeignKey(t => t.App);
Cannot implicitly convert Type 'EndPoints' to 'ICollection'.
Note: EndPoints class is implemented using ObservableCollection.
My question is how to make it work?
Following is my entity definition:
public class ModelBase
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class RuleApp : ModelBase
{
public EndPoints EndPoints { get; set; }
}
public class EndPoint : ModelBase
{
public RuleApp RuleApp { get; set; }
}
public class EndPoints : GenericObservableCollection<EndPoint> { }
public class GenericObservableCollection<T> : ObservableCollection<T>
{
// other common stuff handling
}
This is an Example to do that :
public class ModelBase
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class RuleApp : ModelBase
{
//This for create RelationShip
public virtual ICollection<EndPoint> EndPoints { get; set; }
[NotMapped]
Public EndPoints GenericEndPoints { get; set; }
public void TransferToGenric()
{
GenericEndPoints =new EndPoints(EndPoints)
}
}
public class EndPoint : ModelBase
{
public RuleApp RuleApp { get; set; }
}
public class EndPoints : GenericObservableCollection<EndPoint> { }
public class GenericObservableCollection<T> : ObservableCollection<T>
{
// other common stuff handling
}
If you use GenericObservableCollection as a Property EF Mapped all property in your calss, so I create just a property to use endpoint and after that i transform it to the GenericObserveableCollection.
in the constractor of you EndPoins class you have to featch all data in endpoint to do what you want