We are tasked to refactor an app built using AutoFac and use Unity. We have managed to migrate most of the code, however struggling with one piece, would appreciate if could get an equivalent of the following snippet in Unity
var consumers = typeFinder.FindClassesOfType(typeof(IConsumer<>)).ToList();
foreach (var consumer in consumers)
{
builder.RegisterType(consumer)
.As(consumer.FindInterfaces((type, criteria) =>
{
var isMatch = type.IsGenericType && ((Type)criteria).IsAssignableFrom(type.GetGenericTypeDefinition());
return isMatch;
}, typeof(IConsumer<>)))
.InstancePerHttpRequest();
}
The following should do what you are after:
var openConsumerType = typeof(IConsumer<>);
var consumers = typeFinder.FindClassesOfType(openConsumerType).ToList();
container.RegisterTypes(consumers,
t => t.GetInterfaces()
.Where(i => i.IsGenericType &&
openConsumerType.IsAssignableFrom(i.GetGenericTypeDefinition())),
getLifetimeManager: t => new PerRequestLifetimeManager());
Hopefully my understanding of the FindInterfaces method is close enough.
The PerRequestLifetimeManager should be equivalent to .InstancePerHttpRequest()
Related
In our mvvm-application we are using mvxdialogfragments. Everything works fine under android 4.4, but the exact same code does not work with version 5 lollipop. There are no errors, no exceptions etc. they just don't show up :(
The Dialog is launched from a fragment with those lines:
var myDialog = new CalendarPickerView(){ViewModel = new CalendarPickerViewModel(){CurrentMonth = ViewModel.Day}};
myDialog.Show(Activity.SupportFragmentManager, "Date Selector");
and this happens in the dialogs create-method:
public override Dialog OnCreateDialog(Bundle savedState)
{
_singleLock = true;
ViewModel = MyViewModel;
EnsureBindingContextSet(savedState);
View view = this.BindingInflate(Resource.Layout.CalendarPickerView, null);
var myDialog = new Dialog(Activity, Resource.Style.CustomDialog);
myDialog.SetContentView(view);
MyViewModel.CurrentDate = DateTime.Now.Date;
var leftButton = view.FindViewById<ImageView>(Resource.Id.btn_left);
leftButton.Click += (sender, args) => MyViewModel.MonthBack();
var rightButton = view.FindViewById<ImageView>(Resource.Id.btn_right);
rightButton.Click += (sender, args) => MyViewModel.MonthForward();
cal = view.FindViewById<GridView>(Resource.Id.calendarGrid);
adapt = new CalendarAdapter(Activity);
cal.ItemClick += cal_ItemClick;
adapt.ViewModel = MyViewModel;
MyViewModel.PropertyChanged += MyViewModel_PropertyChanged;
cal.Adapter = adapt;
var saveBtn = view.FindViewById<LinearLayout>(Resource.Id.area_Save);
saveBtn.Click += ((s, a) =>
{
_singleLock = false;
Activity.RequestedOrientation = ScreenOrientation.Sensor;
Dismiss();
});
var abortBtn = view.FindViewById<LinearLayout>(Resource.Id.area_Cancel);
abortBtn.Click += ((s, a) =>
{
_singleLock = false;
Activity.RequestedOrientation = ScreenOrientation.Sensor;
Dismiss();
});
myDialog.SetCancelable(false);
myDialog.SetCanceledOnTouchOutside(false);
return myDialog;
}
If i use DialogFragment instead of MvxDialogFragment as baseclass for CalendarPickerView and remove all mvvm-related code in the create-method, everything works...
Strangely when debugging CalendarPickerView, the fragment ist listed under FragmentManager.Fragments but Dialog.IsShowing is false.
mvvm and xamarin are both the latest stable version by 28.11.2014. Did anybody else encounter this problem or do you have any idea what we could do?
thanks in advance!
I ran into the same problem and for me, the problem was not using MvvmCross or MvxDialogFragment. In my original and also in a separate test project I discovered the following reason for the problem:
It seems that - and I know that it sounds ridiculous - overriding the OnStart () method of DialogFragment even with a body that just includes the base.OnStart () call will prevent the dialog from appearing. Have a look at whether you're using OnStart () in your DialogFragment or somewhere in the inheritance hierarchy.
BTW, I suppose this is not necessarily related to Android 5 / Lollipop but that it is related to the ART runtime. I'll try to confirm this once I get to play with Android 5 device that does not make use of the ART runtime.
I've uploaded the sample project here which can be used to reproduce the issue:
https://github.com/nextmunich/XamarinDialogFragmentTest
My specific problem is how can I automate "add-migration" in a build process for the Entity Framework. In researching this, it seems the mostly likely approach is something along the lines of automating these steps
Open a solution in Visual Studio 2013
Execute "Add-Migration blahblah" in the Package Manager Console (most likely via an add-in vsextention)
Close the solution
This initial approach is based on my own research and this question, the powershell script ultimately behind Add-Migration requires quite a bit of set-up to run. Visual Studio performs that setup automatically when creating the Package Manager Console and making the DTE object available. I would prefer not to attempt to duplicate that setup outside of Visual Studio.
One possible path to a solution is this unanswered stack overflow question
In researching the NuGet API, it does not appear to have a "send this text and it will be run like it was typed in the console". I am not clear on the lines between Visual Studio vs NuGet so I am not sure this is something that would be there.
I am able to find the "Pacakage Manager Console" ironically enough via "$dte.Windows" command in the Package Manager Console but in a VS 2013 window, that collection gives me objects which are "Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase". If there is a way stuff text into it, I think I need to get it to be a NuGetConsole.Implementation.PowerConsoleToolWindow" through reviewing the source code I am not clear how the text would stuffed but I am not at all familiar with what I am seeing.
Worst case, I will fall back to trying to stuff keys to it along the lines of this question but would prefer not to since that will substantially complicate the automation surrounding the build process.
All of that being said,
Is it possible to stream commands via code to the Package Manager Console in Visual Studio which is fully initialized and able to support an Entity Framework "add-migration" command?
Thanks for any suggestions, advice, help, non-abuse in advance,
John
The approach that worked for me was to trace into the entity framework code starting in with the AddMigrationCommand.cs in the EntityFramework.Powershell project and find the hooks into the EntityFramework project and then make those hooks work so there is no Powershell dependency.
You can get something like...
public static void RunIt(EnvDTE.Project project, Type dbContext, Assembly migrationAssembly, string migrationDirectory,
string migrationsNamespace, string contextKey, string migrationName)
{
DbMigrationsConfiguration migrationsConfiguration = new DbMigrationsConfiguration();
migrationsConfiguration.AutomaticMigrationDataLossAllowed = false;
migrationsConfiguration.AutomaticMigrationsEnabled = false;
migrationsConfiguration.CodeGenerator = new CSharpMigrationCodeGenerator(); //same as default
migrationsConfiguration.ContextType = dbContext; //data
migrationsConfiguration.ContextKey = contextKey;
migrationsConfiguration.MigrationsAssembly = migrationAssembly;
migrationsConfiguration.MigrationsDirectory = migrationDirectory;
migrationsConfiguration.MigrationsNamespace = migrationsNamespace;
System.Data.Entity.Infrastructure.DbConnectionInfo dbi = new System.Data.Entity.Infrastructure.DbConnectionInfo("DataContext");
migrationsConfiguration.TargetDatabase = dbi;
MigrationScaffolder ms = new MigrationScaffolder(migrationsConfiguration);
ScaffoldedMigration sf = ms.Scaffold(migrationName, false);
}
You can use this question to get to the dte object and from there to find the project object to pass into the call.
This is an update to John's answer whom I have to thank for the "hard part", but here is a complete example which creates a migration and adds that migration to the supplied project (project must be built before) the same way as Add-Migration InitialBase -IgnoreChanges would:
public void ScaffoldedMigration(EnvDTE.Project project)
{
var migrationsNamespace = project.Properties.Cast<Property>()
.First(p => p.Name == "RootNamespace").Value.ToString() + ".Migrations";
var assemblyName = project.Properties.Cast<Property>()
.First(p => p.Name == "AssemblyName").Value.ToString();
var rootPath = Path.GetDirectoryName(project.FullName);
var assemblyPath = Path.Combine(rootPath, "bin", assemblyName + ".dll");
var migrationAssembly = Assembly.Load(File.ReadAllBytes(assemblyPath));
Type dbContext = null;
foreach(var type in migrationAssembly.GetTypes())
{
if(type.IsSubclassOf(typeof(DbContext)))
{
dbContext = type;
break;
}
}
var migrationsConfiguration = new DbMigrationsConfiguration()
{
AutomaticMigrationDataLossAllowed = false,
AutomaticMigrationsEnabled = false,
CodeGenerator = new CSharpMigrationCodeGenerator(),
ContextType = dbContext,
ContextKey = migrationsNamespace + ".Configuration",
MigrationsAssembly = migrationAssembly,
MigrationsDirectory = "Migrations",
MigrationsNamespace = migrationsNamespace
};
var dbi = new System.Data.Entity.Infrastructure
.DbConnectionInfo("ConnectionString", "System.Data.SqlClient");
migrationsConfiguration.TargetDatabase = dbi;
var scaffolder = new MigrationScaffolder(migrationsConfiguration);
ScaffoldedMigration migration = scaffolder.Scaffold("InitialBase", true);
var migrationFile = Path.Combine(rootPath, migration.Directory,
migration.MigrationId + ".cs");
File.WriteAllText(migrationFile, migration.UserCode);
var migrationItem = project.ProjectItems.AddFromFile(migrationFile);
var designerFile = Path.Combine(rootPath, migration.Directory,
migration.MigrationId + ".Designer.cs");
File.WriteAllText(designerFile, migration.DesignerCode);
var designerItem = project.ProjectItems.AddFromFile(migrationFile);
foreach(Property prop in designerItem.Properties)
{
if (prop.Name == "DependentUpon")
prop.Value = Path.GetFileName(migrationFile);
}
var resxFile = Path.Combine(rootPath, migration.Directory,
migration.MigrationId + ".resx");
using (ResXResourceWriter resx = new ResXResourceWriter(resxFile))
{
foreach (var kvp in migration.Resources)
resx.AddResource(kvp.Key, kvp.Value);
}
var resxItem = project.ProjectItems.AddFromFile(resxFile);
foreach (Property prop in resxItem.Properties)
{
if (prop.Name == "DependentUpon")
prop.Value = Path.GetFileName(migrationFile);
}
}
I execute this in my project template's IWizard implementation where I run a migration with IgnoreChanges, because of shared entites with the base project. Change scaffolder.Scaffold("InitialBase", true) to scaffolder.Scaffold("InitialBase", false) if you want to include the changes.
I created a simple WebAPI service in .NET4 and Visual Studio 2010.
I need to consume that service in a Windows CE / CF 3.5 app
I do have HttpWebRequest available to me, but am not sure if this is the way to go, or I should use RestSharp. Does anybody have insight/experience that would help me decide? I prefer not using 3rd party code when possible to avoid it, but am willing to do so if there is a clear advantage over the "raw" offerings.
Does anyone have, or know of, examples for accessing WebApi services using HttpWebRequest OR RestSharp from CF 3.5?
I have this code (adapted from from http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api) for sample WebAPI methods:
public class VendorItemsController : ApiController
{
VendorItem[] vendorItems = new VendorItem[]
{
new VendorItem { VendorId = "1", VendorItemId = "Tomato Soup", ItemId = "Groceries", PackSize = 1 },
new VendorItem { VendorId = "2", VendorItemId = "V8", ItemId = "Groceries", PackSize = 6 },
new VendorItem { VendorId = "3", VendorItemId = "Garlic", ItemId = "Groceries", PackSize = 1 },
};
public IEnumerable<VendorItem> GetAllProducts()
{
return vendorItems;
}
public VendorItem GetProductById(string id)
{
var vendorItem = vendorItems.FirstOrDefault((p) => p.VendorId == id);
if (vendorItem == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return vendorItem;
}
}
...but don't know how to consume this using, if possible, HttpWebRequest.
Note: HttpClient is not available to me (HttpWebRequest is, though).
UPDATE
I start the VS2010 app that has the WebAPI method; but when I run the VS2008 Windows CE / Compact Framekwork 3.5 app with this code:
Uri _baseAddress = new Uri("http://localhost:48614/");
string localFile = "fetchedVendorItems.txt";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(_baseAddress + "api/vendoritems/");
req.Method = "GET";
HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
// Retrieve response stream and wrap in StreamReader
Stream respStream = resp.GetResponseStream();
StreamReader rdr = new StreamReader(respStream);
// Create the local file
StreamWriter wrtr = new StreamWriter(localFile);
// loop through response stream reading each line and writing to the local file
string inLine = rdr.ReadLine();
while (inLine != null)
{
wrtr.WriteLine(inLine);
inLine = rdr.ReadLine();
}
rdr.Close();
wrtr.Close();
(which I adapted from here: http://msdn.microsoft.com/en-us/library/aa446517.aspx)
...I get, "Unable to connect to the remote server"
UPDATE 2
This does work directly in the browser on the dev machine:
http://localhost:48614/api/redemptions/
It returns these values from a Controller:
readonly Redemption[] redemptions =
{
new Redemption { RedemptionId = "1", RedemptionName = "Old", RedemptionItemId = "ABC", RedemptionAmount = 0.25M, RedemptionDept = "2.0", RedemptionSubDept = "42" },
new Redemption { RedemptionId = "2", RedemptionName = "Damaged", RedemptionItemId = "BCD", RedemptionAmount = 5.00M, RedemptionDept = "42.0", RedemptionSubDept = "76" },
new Redemption { RedemptionId = "3", RedemptionName = "Rebate", RedemptionItemId = "DEF", RedemptionAmount = 42.75M, RedemptionDept = "76.0", RedemptionSubDept = "112" }
};
...like so:
<ArrayOfRedemption xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/HHSServerWebAPI.Models">
<Redemption>
<RedemptionAmount>0.25</RedemptionAmount>
<RedemptionDept>2.0</RedemptionDept>
<RedemptionId>1</RedemptionId>
<RedemptionItemId>ABC</RedemptionItemId>
<RedemptionName>Old</RedemptionName>
<RedemptionSubDept>42</RedemptionSubDept>
</Redemption>
<Redemption>
<RedemptionAmount>5.00</RedemptionAmount>
<RedemptionDept>42.0</RedemptionDept>
<RedemptionId>2</RedemptionId>
<RedemptionItemId>BCD</RedemptionItemId>
<RedemptionName>Damaged</RedemptionName>
<RedemptionSubDept>76</RedemptionSubDept>
</Redemption>
<Redemption>
<RedemptionAmount>42.75</RedemptionAmount>
<RedemptionDept>76.0</RedemptionDept>
<RedemptionId>3</RedemptionId>
<RedemptionItemId>DEF</RedemptionItemId>
<RedemptionName>Rebate</RedemptionName>
<RedemptionSubDept>112</RedemptionSubDept>
</Redemption>
</ArrayOfRedemption>
...even when the VS2008 project is not running - is that because this data was cached (the first time I entered:
http://localhost:48614/api/redemptions/
...in the browser, the Web API app was running)?
I get that the emulator won't recognize "localhost" as the desktop instance, considering itself someone/somewhere else. So how can I test this on an emulator? What IP address can I use?
Avoiding 3rd party code out of hand is just plain silly. Why reinvent the wheel? If you are a company who's IP is making REST calls, then sure, roll it, but I suspect your core business offering is in solving some other problem. I mean why use the CF itself, and not C? Why use C and not assembly? Why use a third-party processor and not design your own?
All that aside, RestSharp comes with source and it's free, so there's little risk in using it. There are some things I like about it - primarily that most of the grunt work for REST calls done. I'm a big fan of not reinventing things. It has some quirks that I've "fixed" locally (I'm meaning to do a pull request, just haven't found the time yet) but they were minor and not what I'd consider to be "typical" cases.
As for calling Web APIs with RestSharp, there's a pretty thorough coverage over in this article.
I've implemented ReCaptcha in MVC3 using ReCaptcha.net NuGet package http://recaptchanet.codeplex.com/wikipage?title=How%20to%20Use%20Recaptcha%20in%20an%20ASP.NET%20MVC%20Web%20Application. All working well, except I'd like to see if I can implement this as Async as it is sometimes quite slow, and we may have some volume on these pages.
The instructions say
RecaptchaVerificationResult recaptchaResult = await recaptchaHelper.VerifyRecaptchaResponse();
if (recaptchaResult != RecaptchaVerificationResult.Success)
{
ModelState.AddModelError("", "Incorrect captcha answer.");
}
however, this is using the MVC4 await syntax. Is there a way I can use this method within the MVC3 async framework?
I did try a quick hack, converting the controller to AsyncController naming the method with an Async suffix and wrapping the entire action in a Task.Factory.StartNew(() => { ... }); while using the non-async syntax, but RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper(); complains about a lack of HTTPContext.
So, can anyone help me with doing ReCaptcha asynchronously in MVC3
In the end, I've dropped using the NuGet package, and simply process the captcha's using the code below, binding the recaptcha fields in the controller method.
public bool ProcessCaptcha(string recaptcha_challenge_field, string recaptcha_response_field)
{
const string verifyUrl = "http://www.google.com/recaptcha/api/verify";
var res = true;
var ip = Request.UserHostAddress;
if (ip == "::1") ip = "127.0.0.1";
var myParameters = string.Format("privatekey={0}&remoteip={1}&challenge={2}&response={3}", Config.CaptchPriv, ip, recaptcha_challenge_field, recaptcha_response_field);
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(verifyUrl, myParameters);
var split = HtmlResult.Split('\n');
if (split[0] == "false") res = false;
}
return res;
}
With this in place, I split my original controller method into a Async/Completed pair, and wrapped the work it does in Task.Factory.StartNew(() => { ... }), following the pattern outlined here http://www.deanhume.com/Home/BlogPost/mvc-asynchronous-controller---the-basics/67 which seems to work perfectly.
Using MVC3.NET I have a file upload method in a controller that works fine with the following signature public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> file)
How can I unit test this with NUnit? I have looked around and everyone seems to point to Moq but I'm new to unit testing and cannot get Moq working.
I have found interesting blogs such as this: http://danielglyde.blogspot.com/2011/07/tdd-with-aspnet-mvc-3-moq-and.html but am struggling to figure out how the same might be done to 'fake' a file upload, and am also wary that a lot on moq examples that I have managed to find now seem to have deprecated code in them.
I would simply like to know how I can simulate a HttpPostedFileBase so I can test my upload code, using Moq or otherwise - I would be really grateful if someone could give me some code examples on how to do this.
The following code taken from other examples on here:
var file = new Mock<HttpPostedFileBase>();
file.Setup(f => f.ContentLength).Returns(1);
file.Setup(f => f.FileName).Returns("test.txt");
controller.upload(file);
generates the following error when I try to compile:
cannot convert from 'Moq.Mock' to
'System.Web.HttpPostedFileBase'
I have changed the method to take a singular HttpPostedFileBase for now, rather than an IEnumerable, as being able to 'mock' one is what I'm trying to focus on for the purpose of this question.
Assuming a standard file upload action:
[HttpPost]
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> files)
{
foreach (var file in files)
{
var filename = Path.Combine(Server.MapPath("~/app_data"), file.FileName);
file.SaveAs(filename);
}
return View();
}
you could test it like this:
[Test]
public void Upload_Action_Should_Store_Files_In_The_App_Data_Folder()
{
// arrange
var httpContextMock = new Mock<HttpContextBase>();
var serverMock = new Mock<HttpServerUtilityBase>();
serverMock.Setup(x => x.MapPath("~/app_data")).Returns(#"c:\work\app_data");
httpContextMock.Setup(x => x.Server).Returns(serverMock.Object);
var sut = new HomeController();
sut.ControllerContext = new ControllerContext(httpContextMock.Object, new RouteData(), sut);
var file1Mock = new Mock<HttpPostedFileBase>();
file1Mock.Setup(x => x.FileName).Returns("file1.pdf");
var file2Mock = new Mock<HttpPostedFileBase>();
file2Mock.Setup(x => x.FileName).Returns("file2.doc");
var files = new[] { file1Mock.Object, file2Mock.Object };
// act
var actual = sut.UploadFile(files);
// assert
file1Mock.Verify(x => x.SaveAs(#"c:\work\app_data\file1.pdf"));
file2Mock.Verify(x => x.SaveAs(#"c:\work\app_data\file2.doc"));
}
Obviously all the HttpContext setup part should be externalized into a reusable class that could be called in the [SetUp] phase of your unit test to prepare the mock context of the subject under test and to avoid repeating it in every single unit test.