I currently have a entity framework repository class that has been based upon the below code I found online.
https://gist.github.com/ashrafeme/060f7773e25903ced986804ee7276f5f
This works fine, however, I'd like to create additional methods that perform specific functions for specific entities. For example, if I had a blog post that needed to filter by Post Type, I could write in my controller
SqlRepository<Blog, MyContext> blogPostRepo = new SqlRepository<Blog, MyContext>(dbContext);
LinkedList<Blog> blogPosts = (LinkedList<Blog>)blogPostRepo.Set<Blog>().Where(p => p.PostType.Id.Equals(2));
However Ideally I would like to just extend the Base SqlRepository Class to create a BlogPostRepository to try and keep the code clean. I'm getting stuck at the minute with the class signatures in my BlogPostRepository. How would I write a class that extends the below base class/
public class SqlRepository<TEntity, TContext> : IRepository<TEntity>, IDisposable
where TEntity : class
where TContext : DbContext
{
enter code here
Create class like:
public class BlogRepository : SqlRepository<Blog, MyContext>
Add a constructor to the derived class with necessary parameters that calls the constructor of the base class (Ref : Link)
Related
I have the code you see below. As such VS defines my two lists in FormMain.cs.design like this: DRT_Tvw_TableList drt_Tvw_TableList; and DRT_Tvw_TableList_Filtered drt_Tvw_TableList_Filtered;
To allow me to leverage inheritence in my code, I want to instead define them like this: DRT_Tvw_Abstract drt_Tvw_TableList; and DRT_Tvw_Abstract drt_Tvw_TableList_Filtered;
So far, all I've been able to do is manually edit the FormMain.cs.design. Is there a way to force VS to use DRT_Tvw_Abstract to define my two treeviews in FormMain.cs.design, e.g., make the abstract class appear in the toolbox so I can drop it onto my form?
public abstract class DRT_Tvw_Abstract : TreeView
{
public DRT_Tvw_Abstract() : base()
{
}
}
public class DRT_Tvw_TableList_Unfiltered : DRT_Tvw_Abstract
{
public DRT_Tvw_TableList_Unfiltered() : base()
{
}
}
public class DRT_Tvw_TableList_Filtered : DRT_Tvw_Abstract
{
public DRT_Tvw_TableList_Filtered() : base()
{
}
}
Update
in practice, I'm using it like this (i.e., manually editing FormMain.Designer.cs to make its code look like the following)
DRT_Tvw_Abstract drt_Tvw_TableList_Unfiltered;
DRT_Tvw_Abstract drt_Tvw_TableList_Filtered;
drt_Tvw_TableList_Unfiltered = new DRT.DRT_Tvw_TableList_Unfiltered();
drt_Tvw_TableList_Filtered = new DRT.DRT_Tvw_TableList_Filtered();
The reason I'm doing this is because there is a boatload of code that the two tree views share. Most of the code is identical for both and as such it is implemented in the abstract class. One difference between the two treeviews is that the treeviews are loaded differently:
drt_Tvw_TableList_Unfiltered is loaded from a datatable. As such, it
has a CreateTreeView(DataTable dataTable) method
drt_Tvw_TableList_Filtered is loaded from
drt_Tvw_TableList_Unfiltered. As such, it has a
CreateTreeView(DRT_Tvw_TableList_Unfiltered
drt_Tvw_TableList_Unfiltered) method
I could implement both these in the abstract (same method name, different arguments), but I chose to implement each in the concrete class to which each belongs.
There are other differences. I deal with them either by writing custom methods in the two concrete classes or overriding abstract class abstract methods in the concrete classes
I want to make VS use the abstract class when it creates its code in FormMain.Designer.cs so I don't have to worry about VS changing them back to the concrete class names and thereby forcing me to manually edit FormMain.Designer.cs again and again
I am reading the following tutorial about asp.net mvc + Entity framework:-
link
and i find that the author is initiating the DbContext object inside the repository class's constructor as follow:-
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
public StudentRepository(SchoolContext context)
{
this.context = context;
}
}
and also the author will be initiating the DBContext object inside the Controller class constructor as follow:-
public class StudentController : Controller
{
private IStudentRepository studentRepository;
public StudentController()
{
this.studentRepository = new StudentRepository(new SchoolContext());
}
public StudentController(IStudentRepository studentRepository)
{
this.studentRepository = studentRepository;
}
//
First Question. can anyone advice what is the purpose of initiating the DBContext object inside the Repository & Controller classes Constructor ? i mean i can replace the repository to be as follow:-
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context = new SchcooleContext
//No need for this constructor !!!
// public StudentRepository(SchoolContext context)
// {
// this.context = context;
// }
and keep the controller class as is ...
second question . do i need to explicitly mention that the repository implements the IDisposable as follow:-
public class StudentRepository : IStudentRepository, IDisposable
now if i remove IDisposable the code should work well.. so what is the purpose of explicitly implementing the IDisposable inside the Repository class ? i mean since i will be calling the StudentRepository.Dispose() method from the Controller class itself,, and the base Controller class by default implement the Idisposable object.. so is there any valid reason to explicitly implement the IDisposable object inside the StudentRepository ?
To answer your questions:
can anyone advice what is the purpose of initiating the DBContext
object inside the Repository & Controller classes Constructor ?
The practice of passing in dependencies in the constructor to the classes that need them is called Dependency Injection. It is generally considered good practice and has great advantages.
Actually, he is not! If you notice, the StudentRepository just accepts a SchoolContext. It never instantiates anything. That means that StudentRepository is happy taking any class that derives from SchoolContext and it can do its work. A common use case is, in production you will pass it the real thing, in testing you may pass it a Mock SchoolContext which never saves to the database but maybe just an in memory list.
You'll notice in StudentController he has 1 constructor which takes an IStudentRepository. This follows the same as above. Any ol' IStudentRepository will do. However, you also notice a constructor which instantiates both classes new StudentRepository(new SchoolContext());. This is actually referred to as Poor Mans Dependency Injection. It's a shortcut. In the real world you would typically see something in some startup config file that says: When a class needs an IStudentRepository give it new StudentRepository(new SchoolContext()).
do i need to explicitly mention that the repository implements the
IDisposable as follow:-
IDisposable
Yes. DbContext implements IDisposable, and so anything that wraps it should as well. The idea is that when you are done with DbConext it needs to be closed. IDisposable communicates that. It is typically used for "unmanaged resources" such as files and connections that need to be "released".
In VS 2010 I'm creating a service reference which code generates the WCF client proxy class Refernce.cs. I need the methods in this class to have the Virtual modifier so they can be used in Mock.
Of course I can hand edit the generated code, but every time I update the reference the code is going to be regenerated and wipe out my changes.
Do I have more control of how the WCF client proxy class is generated? Is there any way to have the code generator always add the Virtual modifier? I would like this to be more automated so that when other developers need to update the reference, they don't have to know or remember to hand edit the generated code and add the the virtual modifier.
An alternative is to create an interface. The proxy classes are generated as partial, which means you can create another partial file for that class, and specify that the class implements your interface, even though the actual implementation is in the generated class. You can then mock the interface, and regenerate your proxy to your hearts content.
For instance, your generated class might be:
public partial class SomeService
{
public string GetSomething()
{
return ...
}
}
You can create an interface for this:
public interface ISomeService
{
string GetSomething();
}
And then add an empty partial file for the generated class:
public partial class SomeService : ISomeService
{
}
I have a base class that has a repository injected into the constructor, now any class that I derive off of it now also needs those parameters, but the repository is only used by the base class, is there a way to bind Ninject to just the base class and not go through the constructor? And most importantly, is it a good idea?
public class HtmlPageModel
{
private readonly IHtmlPageRepository _repository;
public HtmlPageModel (IHtmlPageRepository repository)
{
_repository = repository;
}
}
public class VideoPageViewModel : HtmlPageModel
{
public VideoPageViewModel(IHtmlPageRepository repository) : base(repository)
{
}
}
View models shouldn't have dependencies at all. Inject the repository into the controller and assign the values from there.
Also if many pages are using the same base view model this indicates that some part of the page is shown in many situations or even all the time. In this case it is better to have a custom controller and view for this area and use Html.RenderAction to render this part.
I still stand to my previous comment: You have to rethink your class hierarchy, this is not something you should work around with Ninject.
If your base class accepts a repository, so should all of your derived classes. As an alternative you could however inject a specially NullRepository into your VideoPageViewModel which basically does nothing (see Null Object pattern)
Binding by target type can be achieved using WhenInjectedInto() in Ninject:
kernel.Bind<IHtmlPageRepository>()
.To<HtmlPageRepository>()
.WhenInjectedInto<HtmlPageModel>();
kernel.Bind<IHtmlPageRepository>()
.To<NullRepository>()
.WhenInjectedInto<VideoPageViewModel>();
This is basically the same answer as brokenGlass. Why not just create another base class, and move the attributes/functionality from the your current base class into that one, but don't move the constructor/functionality that relates to the repository.
I have an interface (IRepository<T>) that is currently being extended for each specific repository, ie: IUserRepository : IRepository<User>.
Each of these interfaces has corresponding concrete classes, ie: UserRepository : Repository<User>, IUserRepository.
These individual repositories don't add any additional functionality, they are all empty interfaces/classes that are used simply to pass the generics around.
I use StructureMap to resolve IUserRepository into UserRepository using a Registry with an assembly scanner and some naming conventions.
I'd like this to move to a way more optimised state, where instead of passing around instances of IUserRepository and getting it resolved to UserRepository, I can pass around IRepository<User> and have it resolved to Repository<User>.
This would remove the need to create these extra empty interfaces and classes.
I can't work out a way to use StructureMap's configuration to setup this generic mapping. Something like this:
For(typeof(IRepository<>).Use(typeof(Repository<>)).WithTheGenericTypeFromTheInterfaceSuppliedAsATypeParameter();
Edit
After getting the first couple of answers, I want to clarify this a bit more.
I don't want to create individual classes for the For bit of the configuration. I want to have the following classes/interfaces in my code:
IRepository<T> where T : Entity
Repository<T> : IRepository<T> where T : Entity
Person : Entity
Product : Entity
Order : Entity
Whatever : Entity
And have the following mappings achieved with convention:
IRepository<Person> => Repository<Person>
IRepository<Product> => Repository<Product>
IRepository<Order> => Repository<Order>
IRepository<Whatever> => Repository<Whatever>
But I do not want to have to create a mapping for each one, ala:
For<IRepository<Person>>().Use<Repository<Person>>();
For<IRepository<Product>>().Use<Repository<Product>>();
For<IRepository<Order>>().Use<Repository<Order>>();
For<IRepository<Whatever>>().Use<Repository<Whatever>>();
I want a single mapping that will work for any IRepository:
For<IRepository<>>().Use<Repository<>>().WithTheSameGenericType();
I would then use this to inject the repositories into services:
public MyService(IRepository<User> userRepository)
And expect that to be resolved to a Repository<User> at runtime.
Turns out there is no fancy method to call, or no fancy wiring to do, you just use For and Use (the non generic versions):
public class DataRegistry : Registry
{
public DataRegistry()
{
For(typeof (IRepository<>)).Use(typeof(Repository<>));
}
}
When I inject a IRepository<Person> it is being resolved as a Repository<Person> now.
I encountered error 104 saying Repository wasn't pluggable for IRepository. This was because Repository was marked abstract. Making it non-abstract fixed that error and it is working as desired.
I suggest you to take a look at the AddAllTypesOf method. I had some similar code and achieved my objectives by using it (and kept the auto register feature working).
In your case, you should just change
For<IRepository<Person>>().Use<Repository<Person>>();
For<IRepository<Product>>().Use<Repository<Product>>();
For<IRepository<Order>>().Use<Repository<Order>>();
For<IRepository<Whatever>>().Use<Repository<Whatever>>();
to
AddAllTypesOf(typeof(IRepository<>));
In the end, your container will be similar to:
return new Container(x =>
{
x.Scan(y =>
{
y.TheCallingAssembly();
y.AddAllTypesOf(typeof(IRepository<>));
y.WithDefaultConventions();
});
});
Here is an example. Structure map will allow you to do both also.
//IRepository
For<IMemberRepository>().Add<MemberRepository>();
//IRepository<T>
For<IRepository<Member>>().Add<MemberRepository>();
Then it is useful to ask for the types by just knowing the generic type at runtime:
Type repositoryType = typeof(IRepository<>).MakeGenericType(modelType);
IocResolve.Resolve(repositoryType);
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/12/17/advanced-structuremap-connecting-implementations-to-open-generic-types.aspx
Have a look at IRegistrationConvention interface.
public class DomainRegistry : Registry
{
public DomainRegistry()
: base()
{
Scan(y =>
{
y.AssemblyContainingType<IRepository>();
y.Assembly(Assembly.GetExecutingAssembly().FullName);
y.With(new RepositoryTypeScanner());
});
Where RepositoryTypeScanner:
public class RepositoryTypeScanner : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
...