How to update breeze.js library - breeze

I could use some guidance on how to manually update between versions of Breeze and it's dependencies. I do not believe I can just update with the NuGet Package Manager.
I have been developing my Single Page App with Breeze, Knockout, WebAPI and so forth. I have been using Breeze version 0.61 and want to upgrade to the latest version so I can take advantage of the ODataActionFilters and not have to parse the Request.QueryString to pull out parameters and filters. For example when I call
var getMachineById(machineId) {
var query = EntityQuery
.from("Machines")
.where("machineId", "eq", machineId);
return manager.executeQuery(query)
.then(function (data) {
do_something_with(data.results);
})
.fail(queryFailed);
}
There has to be a way for Breeze to handle that for me, so I can just do something like this:
[AcceptVerbs("GET")]
public IQueryable<Machine> Machines()
{
return _contextProvider.Context.Machines;
}
instead of
// eg "?$filter=machineId%20eq%205"
[AcceptVerbs("GET")]
public IQueryable<Machine> Machines()
{
IQueryable<Machine> x = _contextProvider.Context.Machines;
List<ODataQueryString> list = null;
string qs = Request.RequestUri.Query.ToString(CultureInfo.CurrentCulture);
list = new ODataQueryStringParser(qs).Parse();
if (list != null)
{
int machineId = int.Parse(list[0].Value); // covert string to an int
x = x.Where(o => o.MachineId == machineId);
}
return x;
}
I notice that the Attribute decoration in the Controller has changed in the Samples. Do I need to change mine too?
namespace PilotPlantBreeze.Controllers
{
[JsonFormatter, ODataActionFilter]
public class BreezeController : ApiController
{
readonly EFContextProvider<PilotPlantDbContext> _contextProvider =
new EFContextProvider<PilotPlantDbContext>();
[AcceptVerbs("GET")]
public string Metadata()
{
return _contextProvider.Metadata();
}
[AcceptVerbs("POST")]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
... etc.
}
}
I have my 3rd party libraries in a folder ~\Scripts\lib. If I use the NuGet package manager to update, it puts all the replacements in ~\Scripts. How do I move the files into the lib folder without messing up my Team Foundation Server (Azure) source control?
Are the runtime versions of Antlr3.Runtime.dll, Breeze.WebApi.dll, Irony.dll, Newtonsoft.Json.dll, WebActivator.dll and maybe WebGrease.dll compatible between versions. I bet not. Is there something I have to change in Visual Studio?
Can I just change version entries from the package folder in packages.config?
Thanks.

I think that your best approach would be to remove any existing breeze '.js' files and the webApi and irony.dlls from your project and then simply install the latest breeze nuget package. After installing the nuget package you can go ahead and move the files to other locations within the project to match their "old" locations. I'd do the same for the NewtonSoft nuget package as well, just in case ( breeze will add this back for you). Going forward, you can just update to latest nuget and then move the files.
As you noticed you will also need to replace these attributes
[JsonFormatter, ODataActionFilter]
with this attribute
[BreezeController]
This assumes that you are not running a beta version of ASP.MVC4. I think there are posts in other forums that discuss how to migrate away from the beta.

Related

Trying to add AutoMapper to Asp.net Core 2?

I worked on a asp.net core 1.1 project a while ago and use in projetc AutoMapper.
in asp.net core 1.1, I add services.AddAutoMapper() in startup file :
StartUp file in asp.net core 1.1:
public void ConfigureServices(IServiceCollection services)
{
//Some Code
services.AddMvc();
services.AddAutoMapper();
}
And I use AutoMapper in Controller easily.
Controller :
public async Task<IActionResult> AddEditBook(AddEditBookViewModel model)
{
Book bookmodel = AutoMapper.Mapper.Map<AddEditBookViewModel, Book>(model);
context.books.Add(bookmodel);
context.SaveChanges();
}
And everything was fine.
But I'm currently working on a Asp.net Core 2 project and I get the error with services.AddAutoMapper() in sturtap file.
Error CS0121 The call is ambiguous between the following methods or properties: 'ServiceCollectionExtensions.AddAutoMapper(IServiceCollection, params Assembly[])' and 'ServiceCollectionExtensions.AddAutoMapper(IServiceCollection, params Type[])'
What is the reason for this error?
Also, services.AddAutoMapper in asp.net core 2 has some parameters. what should I send to this parameter?
If you are using AspNet Core 2.2 and AutoMapper.Extensions.Microsoft.DependencyInjection v6.1
You need to use in Startup file
services.AddAutoMapper(typeof(Startup));
You likely updated your ASP.NET Core dependencies, but still using outdated AutoMapper.Extensions.Microsoft.DependencyInjection package.
For ASP.NET Core you need at least Version 3.0.1 from https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/3.0.1
Which references AutoMapper 6.1.1 or higher.
AutoMapper (>= 6.1.1)
Microsoft.Extensions.DependencyInjection.Abstractions (>= 2.0.0)
Microsoft.Extensions.DependencyModel (>= 2.0.0)
The older packages depend on Microsoft.Extensions.DependencyInjection.Abstractions 1.1.0 and can't be used with ASP.NET Core since there have been breaking changes between Microsoft.Extensions.DependencyInjection.Abstractions 1.1.0 and 2.0
In new version (6.1) of AutoMapper.Extensions.Microsoft.DependencyInjection nuget package you should use it as follows:
services.AddAutoMapper(Type assemblyTypeToSearch);
// OR
services.AddAutoMapper(params Type[] assemblyTypesToSearch);
e.g:
services.AddAutoMapper(typeOf(yourClass));
Install package:
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection -Version 7.0.0
Nuget:
https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/
In Startup Class:
services.AddAutoMapper(typeof(Startup));
None of these worked for me, I have a .NET Core 2.2 project and the complete code for configuring the mapper looks like this(part of ConfigureService() method):
// Auto Mapper Configurations
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new SimpleMappings());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
Then I have my Mappings class which I've placed in the BL project:
public class SimpleMappings : Profile
{
public SimpleMappings()
{
CreateMap<DwUser, DwUserDto>();
CreateMap<DwOrganization, DwOrganizationDto>();
}
}
And finally the usage of the mapper looks like this:
public class DwUserService : IDwUserService
{
private readonly IDwUserRepository _dwUserRepository;
private readonly IMapper _mapper;
public DwUserService(IDwUserRepository dwUserRepository, IMapper mapper)
{
_dwUserRepository = dwUserRepository;
_mapper = mapper;
}
public async Task<DwUserDto> GetByUsernameAndOrgAsync(string username, string org)
{
var dwUser = await _dwUserRepository.GetByUsernameAndOrgAsync(username, org).ConfigureAwait(false);
var dwUserDto = _mapper.Map<DwUserDto>(dwUser);
return dwUserDto;
}
}
Here is a similar link on the same topic:
How to setup Automapper in ASP.NET Core
If you are using AspNet Core 2.2.Try changing your code
from:
services.AddAutoMapper();
to:
services.AddAutoMapper(typeof(Startup));
It worked for me.
In .Net 6, you can do it like
builder.Services.AddAutoMapper(typeof(Program).Assembly); // Since there is no Startup file
OR
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
Basically, it requires the assembly name as shown in screenshot below
I solved this by creating a class that inherits AutoMapper.Profile
public class model_to_resource_profile : Profile
{
public model_to_resource_profile()
{
CreateMap<your_model_class, your_model_resource_class>();
}
}
And adding this line in the Startup.cs:
services.AddAutoMapper(typeof(model_to_resource_profile ));
try this, works with 2.1 and up, i have not used any previous version so can't tell.
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
The official docs:
https://automapper.readthedocs.io/en/latest/Dependency-injection.html#asp-net-core
You define the configuration using profiles. And then you let
AutoMapper know in what assemblies are those profiles defined by
calling the IServiceCollection extension method AddAutoMapper at
startup:
services.AddAutoMapper(profileAssembly1, profileAssembly2 /*, ...*/);
or marker types:
services.AddAutoMapper(typeof(ProfileTypeFromAssembly1), typeof(ProfileTypeFromAssembly2) /*, ...*/);
If you are having issue with adding your auto mapper, It is better you check through the type and version you added.
If it is not "AutoMapper.Extensions.Microsoft.DependencyInjection", then you won't be able to use "services.AddAutoMapper()".
Sometimes, you might mistakenly add "AutoMapper
Dec 6th 2019 Based upon initial attempt in a pluralsight course Building an API with ASP.NET Core by Shawn Wildermuth. As I got the error "...ambiguous 'ServiceCollectionExtensions.AddAutoMapper(IServiceCollection, params Assembly[])..."
I started researching proper syntax to implement AddAutoMapper in Core 2.2. My NuGet reference is version 7.0.0 After the tutorial had me create the Profile class in my Data repository directory which additionally referenced my model nir weiner & dev-siberia's answers above led me to trying to reference the profile class in the Startup.ConfigureServices() by name:
services.AddAutoMapper(typeof(CampProfile));
the content of the profile class is just a (no pun intended) old school map of the data class and the model in its constructor
this.CreateMap<Camp, CampModel>();
This addressed the poor lack of documentation for this current version.
Respectfully,
ChristianProgrammer

Use ASP.NET MVC Unity for Data Caching

I have a ASP.Net MVC project running on .NET 4.6.1 Framework.
I have recently added Unity.Mvc 5 IoC framework for dependency injection
In order to have flexibility for unit testing and other, I moved my Unity Configuration to a separate class library so that I can call the Unity Register methods from Unit test projects and other as needed.
Here is my high-level solution design.
I would like to use the same class library to implement application cache.
When I installed Unity.Mvc5 from nuget package it added following references (I added some of them manually) :
Microsoft.Practices.EnterpriseLibrary.Caching 5.0.505.0
Enterprise Library Shared Library 5.0.505.0
Microsoft.Practices.ServiceLocation 1.3.0.0
Microsoft.Practices.Unity 4.0.0.0
Microsoft.Practices.Unity.Configuration 4.0.0.0
Microsoft.Practices.Unity.Interception 2.1.505.0
Microsoft.Practices.Unity.Interception.Configuration 2.1.505.0
Microsoft.Practices.Unity.RegistrationByConvention 4.0.0.0
I tried few articles to implement Application Block Cache Management so that I can cache data in my Service Implementer layers, but all those documentations are showing code examples which is expecting Unity 2.xxx version.
Here is my Unity Configuration
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<UserManager<User>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<User>, UserStore<User>>(new HierarchicalLifetimeManager());
container.RegisterType<DbContext, OfficeGxDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<IAppSetting, AppSettingService>();
container.RegisterType<ISubscription, SubscriptionService>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
In my AppSettingService.cs I have get all method
public List<AppSetting> All()
{
using (var context = new MyDbContext())
{
//CachecKeyItem.AppSettingsAll
return context.AppSettings.Where(x => !x.IsDeleted)
.Include(x => x.Module).ToList();
}
}
I want to store this data in cache and reuse it. Similarly do this across all projects I have in my solution and if there is any update or add or delete for any DB records, I want the cached object to refresh it so that cached object is always in sync with DB data
I ended up doing something like this
public interface ICacheService
{
T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class;
}
Service Implementor
public class InMemoryCache : ICacheService
{
public T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class
{
if (MemoryCache.Default.Get(cacheKey) is T item) return item;
item = getItemCallback();
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(8));
return item;
}
}
use like this
_cacheService.GetOrSet(CachecKeyItem.AppSettingsAll, () => context.AppSettings
.Where(x => !x.IsDeleted)
.Include(x => x.Module).ToList());
Now my question is, when there is any change to data, like add/edit/delete, how do I refresh the cache in most efficient way? I know deleting the key would be one, is there a better way?
It slightly depends on if your running in a single server system or multi server system. Its generally better to always design for multi-server that way if you ever decide to scale out your already sorted.
So assuming you can get a message to fire off when your cache invalidates to all the servers without issue then the easiest way is to delete your cache key... now that also brings a few areas of optimization that can be looked at.
Is this cached data utilized heavily, in which case may you benefit from a pre-fetch cache where you either send the updated cached entry to all servers or require all servers to ask for it? Is it used very little in which case you don't really want to re-populate until its requested otherwise your needlessly bloating your application.

Projects with StructureMap and Unobtrusive don't register Subscriptions

Current Production NUGET build.
Windows 8 x64
VS2012
I followed the sample on how to create a pub/sub.
The default builder was swapped out for structuremap, and everything worked fine.
I delete the queues and the database for raven and the console complains about client#machine name doesn't exist.
I delete the queues and db again and comment out the structuremap stuff and restore the default builder and everything works again.
Same problem with new projects that don't use the default builder to setup the queues first.
Initial
Configure.With()
.DefaultBuilder()
.DefiningEventsAs(t => t.Namespace != null && t.Namespace.EndsWith("Events"));
With StructureMap
public void Init()
{
Configure.With()
//.DefaultBuilder()
.StructureMapBuilder(new Container(new DependencyRegistry()))
.JsonSerializer()
.DefiningEventsAs(t => t.Namespace != null && t.Namespace.EndsWith("Events"));
}
public class DependencyRegistry : Registry
{
public DependencyRegistry()
{
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory();
x.WithDefaultConventions();
});
}
}
DefiningEventsAs needs to go right after the call to With(). This is a known issue we'll make sure to fix it in a future version.

EF4 Repository Pattern problems injecting repository into service .Cannot seem to get it right

I am finding difficult to test EntityFramework 4 .I am using it using the database first approach,too late now to move to poco.Needed to deliver pretty quickly,no time to learn properly as usual.
I have implemented the repository pattern with unit of work but I am finding difficult to inject a repository into my Service layer so that I can test the behaviour of my business layer service ,validation etc... without hitting the db.
but I am incurring in many little problems.
In order to inject the Repository into the service(constructor) the calling layer need to have a reference to the DAL (EF Entities) . I dont want this
If i have many repositories EG CustomerRepository ,EmployeeRepository than I need to have as many constructors as repositories so that I can inject the repository.
3.Not sure where to go from here. I have not found any example on the net where they inject the repository into the service using EF4. All the examples I have seen they mock the repository on it's own,which is not good to me.
I need to test my service layer/BizLayer without hitting the database.
The all thing is just not testable and adds so many dependencies and problems.
Noddy example I have put together
public class DepartmentServiceLibrary
{
private readonly IDepartmentRepository _departmentRepository;
public DepartmentServiceLibrary(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
return DeparmentBiz.GetDepartments();
}
private DeparmentBL _departmentBiz;
private DeparmentBL DeparmentBiz
{
get
{
return _departmentBiz ?? new DeparmentBL(_departmentRepository);
}
}
}
//internal class
internal class DeparmentBL
{
private readonly IDepartmentRepository _departmentRepository;
public DeparmentBL(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
using (var ctx = new AdventureWorksContext())
{
var uow = new UnitOfWork(ctx);
_departmentRepository.UnitOfWork = uow;
var query = _departmentRepository.GetAll();
return query.Select(dpt => new DepartmentDto
{
DepartmentId = dpt.DepartmentID,
Name = dpt.Name,
GroupName = dpt.GroupName
}).ToList();
}
}
}
The following TestMethod requires me to add a ref to the dal which defeats the point
[TestMethod]
public void Should_be_able_to_call_get_departments()
{
var mock = new Mock<IDepartmentRepository>();
var expectedResult = new List<Department>(); //Dependency to DAL as Department is a EF Entity generated by EF.
mock.Setup(x => x.GetAll()).Returns(expectedResult);
var companyService = new MyCompanyBL(mock.Object); //InternalVisibileTO
var departments = companyService.GetAll();
//assert removed for brevity
Any suggestions or examples out there that shows how to do it?
thanks
}
The short answer is - since you're not using POCOs, all your layers will have a reference to your DAL.
Without POCOs, you use code generation, which means EF creates the model classes in the Model.edmx.designer.cs file.
An option (haven't tried this - off the top of my head) is to manually project the EF entities into DTOs.
So your Repository might do this:
public List<OrderDTO> GetOrdersForCustomer(int customerId)
{
return _ctx.Orders
.Where(x => x.CustomerId == customerId)
.ToList()
.Select(x => new OrderDTO { // left to right copy });
}
The OrderDTO class could be in a separate assembly, which the repository references, as well as your other projects. So the other projects would work off the DTO assembly, and wouldn't require a reference to the Repository.
But here you're projecting into classes everywhere (basically doing POCO, but manually, and with more work) left to right copying of properties - very painful.
However, that is an option.
Honestly - it does not take long to move to POCOs.
There is a T4 template which will generate the POCOs for you - you could be up and running in a matter of minutes.
And since you're already using dependency injection and repository, you should either bite the bullet and change to POCOs, or keep the reference to the DAL.
Something similar in terms of code can be seen here in GitHub
and detail explanation can be found in TechNet

Cannot get assembly version for footer

I'm using the automatic build versioning mentioned in this question (not the selected answer but the answer that uses the [assembly: AssemblyVersion("1.0.*")] technique). I'm doing this in the footer of my Site.Master file in MVC 2. My code for doing this is as follows:
<div id="footer">
webmaster#foo.com - Copyright © 2005-<%= DateTime.Today.Year.ToString() %>, foo LLC. All Rights Reserved.
- Version: <%= Assembly.GetEntryAssembly().GetName().Version.ToString() %>
</div>
The exception I get is a Object reference not set to an instance of an object because GetEntryAssembly() returns NULL. My other options don't work either. GetCallingAssembly() always returns "4.0.0.0" and GetExecutingAssembly() always returns "0.0.0.0". When I go look at my DLLs, everything is versioning as I would expect. But I cannot figure out how to access it to display in my footer!!
That's because Assembly.GetEntryAssembly() is returning null: there is no "entry" assembly in an ASP.NET site (because the .NET framework is hosted in the w3wp.exe process). Assembly.GetEntryAssembly() is used to get the .exe assembly that you launched from (usually in a console or Windows application)
The reason Assembly.GetAssembly(this.GetType()) is returning an assembly with version "0.0.0.0" is because ASP.NET compiles your Site.Master file into a temporary assembly under your "ASP.NET Temporary Files" folder. this is a reference to the "generated" class.
Assembly.GetExecutingAssembly() is basically the same as Assembly.GetAssembly(this.GetType()) (except it also works when there is no "this" (e.g. in static methods).
The best way would be use explicity use a type that you know exists in the assembly you're after. As an example, I assume your "Site.Master" has a code-behind file that is compiled into the assembly. You can use that instead:
Assembly.GetAssembly(typeof(Site)).GetName().Version.ToString()
(assuming the name of the class is Site)
Just as another solution that people may be interested in, I've concocted these helpers to help with this problem:
public static class HtmlHelperExtensions
{
private static string _CachedCurrentVersionDate;
/// <summary>
/// Return the Current Version from the AssemblyInfo.cs file.
/// </summary>
public static string CurrentVersion(this HtmlHelper helper)
{
try
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
return version.ToString();
}
catch
{
return "?.?.?.?";
}
}
public static string CurrentVersionDate(this HtmlHelper helper)
{
try
{
if (_CachedCurrentVersionDate == null)
{
// Ignores concurrency issues - assuming not locking this is faster than
// locking it, and we don't care if it's set twice to the same value.
var version = Assembly.GetExecutingAssembly().GetName().Version;
var ticksForDays = TimeSpan.TicksPerDay * version.Build; // days since 1 January 2000
var ticksForSeconds = TimeSpan.TicksPerSecond * 2 * version.Revision; // seconds since midnight, (multiply by 2 to get original)
_CachedCurrentVersionDate = new DateTime(2000, 1, 1).Add(new TimeSpan(ticksForDays + ticksForSeconds)).ToString();
}
return _CachedCurrentVersionDate;
}
catch
{
return "Unknown Version Date";
}
}
}
This allows consumption as follows in your footer:
Version: <%= Html.CurrentVersion() %> from <%= Html.CurrentVersionDate() %>
You can:
e.g in your Application_Start method in Global.asax file add
protected void Application_Start(object sender, EventArgs e)
{
HttpContext.Current.Application.Add("Version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
}
in HTML show it by
<div><% =HttpContext.Current.Application["Version"].ToString() %></div>
ALSO Change Assembly version to 1.0.0.* by going to
- Project properties > Application > Assembly Information and assembly version is shown as 1.0.0.0 - change it to 1.0.0.*
this will give you some versioning
If you already have Global.asax in place, it could be a good place to store version globally once.
Global.asax.cs:
public class Global : HttpApplication
{
public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version;
}
Your view:
<div>- Version: #YourNamespace.Global.Version</div>

Resources