I used to use DbContext for all of my DB Models, until I read Ways to optimize Entity Framework, after following the steps I found my self forced to switch to ObjectContext instead, So, There were alot of code changes to be done, but I am not sure that I doing the right thing, specially after Googling the deference I've noticed that DbContext is newer and better than ObjectContext, and also I noticed that I lost alot of things while switching to ObjectContext like "Migrations" and "Find" Method and much more...
So, Is the right thing to change my code to use ObjectContext instead of DbContext to increase the speed by Pre-Generating the Views ? or am I doing something wrong ?
You should not have to switch to ObjectContext to get pre-generated views. I created T4 templates for generating pre-generated views for CodeFirst. Take a look here: Entity Framework initialization is SLOW -- what can I do to bootstrap it faster?
The T4 templates are available on Visual Studio Gallerry. Here is the link to my blog post describing how to get and use them
I would encourage you to use DbContext as it is a simplified version of the ObjectContext. If the DbContext is not suffice, the wrapped ObjectContext can be accessed from the DbContext:
((IObjectContextAdapter)dbContext).ObjectContext
The "Generate Views" option is also available for Code First (DbContext) in EF Power Tools. Right-click a file derived from DbContext and select "Entity Framework" => "Generate Views". For more information see Generating Pre-compiled Views
Related
According to the Simple Injector documentation on WebForms integration, it says, with code examples, that we are supposed to do property injection into our Pages by utilizing the [Import] attribute. And we enable this behavior by wiring up the Global.asax file according to their code samples. And it does work for Pages. There is nothing in the documentation for UserControls or MasterPages, however.
In scouring StackOverflow for a solid answer, the ubiquitous response is slightly outdated and references creating an HttpModule, providing a link to an example project found in their git repo (SimpleInjector.Integration.Web.Forms). That example project is dead and culled from the repo as of Simple Injector v4.0, though. And it does not utilize the [Import] attribute stuff at all. Definitely confusing.
So without a clear idea of how to move forward, I've attempted to merge the two in order to get this working properly.
I am using the Global.asax bootstrapper approach as detailed in the most recent documentation, and not registering a new HttpModule. I took the container extension methods as defined in the old WebForms integration project, and am calling those in my Bootstrap instead of the old method.
private static void Bootstrap()
{
var container = new Container();
//container.Options.PropertySelectionBehavior = new ImportAttributePropertySelectionBehavior(); //approach from latest documentation
container.Options.PropertySelectionBehavior = new SimpleInjector.Integration.Web.Forms.WebFormsPropertySelectionBehavior(container.Options.PropertySelectionBehavior); //changed to using WebForms integration way
...
//RegisterWebPages(ref container); //approach from latest documentation
container.RegisterPages(); //changed to using WebForms integration extension methods
}
When I first ran it, the container.Verify() complained that every Page implements IDisposable and that they're being registered as Transient (this perplexes me because the original bootstrapping seemed to also register Pages as Transient, but does Verify did not throw any errors).
So, to fix this, I modified the RegisterPages extension method to default to Lifestyle.Scoped, which removed the Verify errors.
private static void RegisterBatchAsConcrete(this Container container, IEnumerable<Type> types)
{
foreach (Type concreteType in types)
{
//container.Register(concreteType); //originally registering Transient
container.Register(concreteType, concreteType, Lifestyle.Scoped);
}
}
And it seems to work now, at least for Pages. Before moving forward with getting this working for UserControls and MasterPages, I would like to know answers to the following:
Questions
Is this the right approach? Am I going to run into issues (performance, or otherwise) because I changed the Page, MasterPage, and UserControl registration from Transient to Scoped lifestyle? Are there any other gotcha's I'm not thinking of?
Why does Verify have a problem with Tranisent Lifestyle with the RegisterPages extension method call vs. the new RegisterWebPages method?
Should I actually be using the Import attribute, or no? The new approach uses the ImportAttributePropertySelectionBehavior, while the old approach utilizes WebFormsPropertySelectionBehavior
That example project is dead and culled from the repo as of Simple Injector v4.0, though.
The SimpleInjector.Integration.Web.Forms) was built a long time ago and was meant to become the solution for integrating Web Forms with Simple Injector. Since the lack of interest from the community (i.e. there were just too few developers interested in integrating Simple Injector with Web Forms), we decided not to invest in publishing this as NuGet package, maintain it, create documentation, fix bugs, have support for it, etc.
Since Web Forms is a legacy technology, we eventually decided to pull the project from the repository, knowing that we could always reference to older branches.
And it does not utilize the [Import] attribute stuff at all. Definitely confusing.
That's not true. [Import] will work as well, but as the documentation describes, you will have to plug in your custom ImportAttributePropertySelectionBehavior.
Why does Verify have a problem with Transient Lifestyle with the RegisterPages extension method call vs. the new RegisterWebPages method?
The integration guide for Web Forms suppresses the DisposableTransientComponent warning, so that's what you'll have to do as well. The reason this does not happen in the integration project is because this project was created during the v2.x timeframe, and at that time, the verification wasn't that strict. The project has never been updated since.
Is this the right approach? Am I going to run into issues (performance, or otherwise) because I changed the Page, MasterPage, and UserControl registration from Transient to Scoped lifestyle? Are there any other gotcha's I'm not thinking of?
You should absolutely not register your classes and user controlers as scoped, because you will run into serious trouble, really quickly. Especially for user controls, it is really common to have multiple instances of the same control in the page. Registering them as Scoped causes the same instance to be placed at multiple places in the page, which will obviously cause trouble (if it works at all).
So you should definately keep user controls (and pages probably as well) registered as Transient, and suppress the DisposableTransientComponent warning instead. DisposableTransientComponent can be suppressed, because ASP.NET will dispose everything for you when the request ends.
Should I actually be using the Import attribute, or no? The new approach uses the ImportAttributePropertySelectionBehavior, while the old approach utilizes WebFormsPropertySelectionBehavior
The ImportAttributePropertySelectionBehavior implements Explicit Property Injection using the [Import] attribute, while WebFormsPropertySelectionBehavior implements Implicit Property Injection.
That decision what to use is up to you, but Explicit Property Injection should in general be preferred, because of the downsides of Implicit Property Injection (that the documentation describes).
I want to separate my ASP. NET MVC 5 + WebApi2 solution into separate logical projects, so (in my head) I have:
Data.csproj
references EF6 and handles Code First migrations
Models.csproj
references Automapper
refrences Data (above)
Services.csproj
references Models (above)
Web.csproj
references autofac
references services above
But I can't get my real project to look like that because
Identity sprinkles the model and EF references all over my Web.csproj
When I configure Autofac in Web.csproj and try to register my DbContexts and whatever other dependencies are in my other projects, I will need access to the concrete types, so Web will need to reference all other projects as the DI is setup in Web?
This is a brand new project auto-generated by the ASP .NET template. Thanks.
Generally, you avoid getting your Entity-Framework pollution into your web code by not referencing your data-models in your web project.
If you put interfaces for the models in a separate infrastructure project, for example, you won't have that problem any more. Your 'services' can return abstract types with no dependency on EF and coupling is reduced.
Personally, I like to get around this problem wither with a separate project that is responsible for factory code or (even better IMO) giving each project responsibility for constructing its own objects. Having the factory code in the same place further reduces coupling and can make refactoring easier.
One more thing...
If this is a new project, why do you even need a DI container. You could always use poor man's dependency injection and refactor later when you have a better idea of your needs. They are often overused or used as a crutch to hide overly complex lasagna code. It is an incredibly useful and powerful technology, but most of the benefit in terns of flexibility can also be realised through well designed factories and builders. These can have the additional benefit of increased readability.
I'm using Caliburn micro with a WinRT application and it looks like that there's no StorageManager class, anyone has suggestions about how to persist application/ViewModels state in this case.
TIA
This is not related to Caliburn.Micro but rather a general issue. You can either use Serialization but then you will have to pay attention to versioning and changes in your view model or you could save the fields you are interested in to a file using the normal IO methods or even store your view models in the database if you wish (although i think this might be a bit extreme).
Edit: Caliburn.Micro isn't a business application framework and there have been no library that tried to integrate business functionality with CM as far as i know, so this leaves you with serialization as your best option but as i said ser/des comes with some nightmares you have to manage such as version changes, class changes, etc.
There's another project called Catel which is a business application framework that contains an MVVM framework, anyway Catel uses a nice object called DataObjectBase ( actually now it is called ModelBase) which solves all problems of serialization and there is an article for that on code project if you want to read it and see how they have done it.
If you wish you can use the Catel.Core module which is a library with a lot of features for data handling (it contains the ModelBase class) or you can take a look at the source code and see how they have solved the issue with ser/des and implement that with Caliburn.Micro in your project.
What are the required steps to use SimpleMembership (ASP.NET MVC 4) with RavenDB (or other databases) instead of SQL Server?
I am used to override the MembershipProvider but how does it work with the new SimpleMembership?
I saw there is a SimpleMembershipProvider so I think I should override it, but I don't know if the methods are for storing data purpose only or if they should contain business/validation logic)...
What about configuration? I know the InitializeDatabaseConnection method is normally responsible for initializing the whole shebang, but I don't think I should call it if I don't use Entity Framework.
Unfortunately, I did not find a lot of resources about the new SimpleMembership except two links which have not been very useful:
http://igambin.blogspot.ca/2012/08/simplemembershipprovider-huh.html
http://blog.osbornm.com/archive/2010/07/21/using-simplemembership-with-asp.net-webpages.aspx
So here is what I found after looking at some of the the source code (MVC4).
http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/553690ac9488#src%2fWebMatrix.WebData%2fExtendedMembershipProvider.cs
SimpleMembership is an implementation of the abstract class ExtendedMembershipProvider.
The code inside SimpleMembership is mostly SQL operations and some calls to the underlying (called "previous" in the documentation) MembershipProvider.
I don't think it is of any use (in my case) to override SimpleMembership as its implementation is mostly tied to SQL Server. Instead, for what I understand, I should implement ExtendedMembershipProvider. Then, by setting this implementation in the web.config file, the WebSecurity helper would bypass SimpleMembership (default implementation) and call my implementation of the ExtendedMembershipProvider.
I don't think I will do this any soon since it looks even more complicated than before (more methods to implement)... but still doable.
However, all this said, I'm a bit disappointed that we still have to work with the MembershipProvider which, IMHO, is far (a lot of static and internal stuff) from the whole dependency injection thing that we love so much with ASP.Net MVC/WebApi.
Edit 1
This question was aked before Jon Galloway wrote this tutorial :
http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx
But my answer stays valid as this (taken from Jon Galloway article) resumes it:
Note that SimpleMembership still requires some flavor of SQL Server -
it won't work with MySQL, NoSQL databases, etc. You can take a look at
the code in WebMatrix.WebData.dll using a tool like ILSpy if you'd
like to see why - there are places where SQL Server specific SQL
statements are being executed, especially when creating and
initializing tables. It seems like you might be able to work with
another database if you created the tables separately, but I haven't
tried it and it's not supported at this point.
Here's my implementation for mongodb. Maybe it can help
https://github.com/malibeg/MongodbSimpleMembershipProvider#readme
SimpleMembership is not really meant to be used with the old MembershipProviders as it doesn't fullfill all of the same contracts that are assumed of normal MembershipProviders. Its mostly designed for use via the WebSecurity helper.
This link might be helpful for more info: Web Pages Tutorial
I'm currently working on a project that uses Entity framework for data persistence. It started using Entity Framework 4 with EDMX and T4 template and ObjectContext with Objectset.A lot of Complied queries have been used for improving the query performance.
However, the approach is not extensible anymore because project team size has increased and Test Driven development need to be implemented. So we took the decision to convert using entity object in to POCO and DbContext for the support of Test Driven Development for repository integration test with data migration.
Unfortunately, we have realized that there is no support for complied queries for DbContext.
We decided to use two separate inherited context classes from DbContext for (CRUD) and ObjectContext (Complied Queries), as in near future we can shift to auto compile query support with DbContext.
My Questions are
What are the consequences with can be occurred by implementing this approach ?
Is there any alternative approach ?
Thanks