I need a custom insert / add member function for my "entity manager class" which is only responsible of many entities.
For this I define a std::vectorstd::unique_ptr<cEntity> listOfEntities as private in this class.
But how can I add entities to the vector?
Following situation:
class cEntity
{
public:
void setName(const std::string& newName)
{
name = newName;
};
private:
std::string name;
};
class cEntityMgr
{
public:
cEntityMgr() { listOfEntities.clear(); };
void addEntity(const cEntity& aEntity)
{
listOfEntities.push_back(aEntity); // this doesn´t work
};
private:
std::vector<std::unique_ptr<cEntity>> listOfEntities;
};
int main()
{
//
cEntityMgr myFirstEntityMgr;
// add a new entity to my entity manager
myFirstEntityMgr.addEntity(std::make_unique<cEntity>("My First Entity") ); // I don´t want to use any new call here
}
Related
I generally store away all the command line options to a different class, say, CliArguments. This avoids the noise in the main class. This is what I have with picocli:
public final class MyApp {
private static final CliArguments cliArgs = new CliArguments();
private MyApp() {}
public static void main (String[] args) {
if (parseArgs (args)) {
new MyApp().execute();
}
}
/* want to avoid this boiler plate */
private static boolean parseArgs(String[] args) {
CommandLine cmd = new CommandLine ( cliArgs );
try {
cmd.parseArgs( args );
if (cmd.isUsageHelpRequested()) {
cmd.usage( cmd.getOut() );
return false;
}
else if ( cmd.isVersionHelpRequested() ) {
cmd.printVersionHelp (cmd.getOut());
return false;
}
logger.info("{}", cliArgs);
return true;
}
catch ( ParameterException ex ) {
logger.error ("Failure to parse : {}", ex);
return false;
}
}
private void execute() {
// execution logic
}
}
How do I avoid the boiler plate method, pargeArgs(String[])? The CliArguments class, technically, should not implement a Callable or Runnable. I can make MyApp be a Callable or Runnable. but to CommandLine, new MyApp() is not a command, new CliArguments() is.
If I want to do something like this:
final int exitCode = new CommandLine(new MyApp()).execute(args);
if (0 != exitCode) {
logger.error("Failed to parse");
System.exit(exitCode);
}
how do I push off all the #Option specification to a different class, CliArguments while still having the execution control in MyApp?
I am sure I am missing something straight forward.
The simplest way to achieve this is by making CliArguments a mixin in MyApp. We can then put the business logic in MyApp, and make it a Runnable or Callable so we can bootstrap the application with new CommandLine(new MyApp()).execute(args).
For example:
#Command(mixinStandardHelpOptions = true, version = "1.0.0")
public class CliArgs {
#Option(names = "-x") boolean x;
#Option(names = "-y") boolean y;
}
#Command(name = "myapp", description = "...")
public class MyApp implements Runnable {
// options defined in the mixin are added to this command
// also, #Command attributes from the mixin are applied to this command
#Mixin
CliArgs cliArgs;
public void run() {
System.out.printf("-x=%s%n", cliArgs.x);
System.out.printf("-y=%s%n", cliArgs.y);
}
public void main(String... args) {
System.exit(new CommandLine(new MyApp()).execute(args));
}
}
The options defined in the CliArgs mixin become part of the MyApp mixee.
Also, any #Command attributes defined in CliArgs become part of the MyApp command.
You can now run:
java MyApp -x
and this will print
-x=true
-y=false
Since the mixin has #Command(mixinStandardHelpOptions = true), the MyApp command also has --help and --version options that work as you would expect.
I have a problem with mocking cause it keep calling the original function. This is my demo code
First file is interface that contains the function that I want to mock.
public interface IDemoReplace
{
int FunctionToBeReplaced();
}
Second file is a class that actually has the implementation for the function
public class DemoReplace : IDemoReplace
{
public int FunctionToBeReplaced()
{
//this function contains sql query in my real project
return 1;
}
}
Third file is a class that I want to test
public class ClassToBeTested
{
public int TestThisFunction()
{
IDemoReplace replace = new DemoReplace();
var temp = replace.FunctionToBeReplaced();
return temp;
}
}
Last file is the test class
public class TestClass
{
[Fact]
public void TryTest()
{
using (var mock = AutoMock.GetLoose()) {
//Arrange
mock.Mock<IDemoReplace>()
.Setup(x => x.FunctionToBeReplaced())
.Returns(returnTwo());
var classToBeTested = mock.Create<ClassToBeTested>();
var expected = 2;
//Act
var actual = classToBeTested.TestThisFunction();
//Assert
Assert.Equal(expected, actual);
}
}
public int returnTwo() {
return 2;
}
}
This test will be failed with expected is 2 and actual is 1. When I tried to debug it doesn't call returnTwo but call the original function instead.
I am new to unit testing so what did I miss? Please be considered that the code above is only a demo of what is happened in my actual project. FunctionToBeReplaced is actually a function that execute and return record from database so I want to mock that function.
Thanks :)
This is a design issue. The subject under test is tight coupled to implementation concerns that make it difficult to isolation the subject so that it can be unit tested.
It (subject) is manually creating its dependency
IDemoReplace replace = new DemoReplace();
Ideally you want to explicitly inject dependencies. Those dependencies should also be abstractions and not concretions.
public class ClassToBeTested {
private readonly IDemoReplace dependency;
public ClassToBeTested(IDemoReplace dependency) {
this.dependency = dependency;
}
public int TestThisFunction() { ;
var temp = dependency.FunctionToBeReplaced();
return temp;
}
}
At run time, the implementation (or mock) can be injected, either purely, or via a container.
The test in the original example shown should now behave as expected.
public class TestClass {
[Fact]
public void TryTest() {
using (var mock = AutoMock.GetLoose()) {
//Arrange
var expected = returnTwo();
mock.Mock<IDemoReplace>()
.Setup(x => x.FunctionToBeReplaced())
.Returns(expected);
var classToBeTested = mock.Create<ClassToBeTested>();
//Act
var actual = classToBeTested.TestThisFunction();
//Assert
Assert.Equal(expected, actual);
}
}
public int returnTwo() {
return 2;
}
}
I have the following layout for my mvc project:
/Controllers
/Demo
/Demo/DemoArea1Controller
/Demo/DemoArea2Controller
etc...
/Views
/Demo
/Demo/DemoArea1/Index.aspx
/Demo/DemoArea2/Index.aspx
However, when I have this for DemoArea1Controller:
public class DemoArea1Controller : Controller
{
public ActionResult Index()
{
return View();
}
}
I get the "The view 'index' or its master could not be found" error, with the usual search locations.
How can I specify that controllers in the "Demo" namespace search in the "Demo" view subfolder?
You can easily extend the WebFormViewEngine to specify all the locations you want to look in:
public class CustomViewEngine : WebFormViewEngine
{
public CustomViewEngine()
{
var viewLocations = new[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx",
"~/AnotherPath/Views/{0}.ascx"
// etc
};
this.PartialViewLocationFormats = viewLocations;
this.ViewLocationFormats = viewLocations;
}
}
Make sure you remember to register the view engine by modifying the Application_Start method in your Global.asax.cs
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
}
Now in MVC 6 you can implement IViewLocationExpander interface without messing around with view engines:
public class MyViewLocationExpander : IViewLocationExpander
{
public void PopulateValues(ViewLocationExpanderContext context) {}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
return new[]
{
"/AnotherPath/Views/{1}/{0}.cshtml",
"/AnotherPath/Views/Shared/{0}.cshtml"
}; // add `.Union(viewLocations)` to add default locations
}
}
where {0} is target view name, {1} - controller name and {2} - area name.
You can return your own list of locations, merge it with default viewLocations (.Union(viewLocations)) or just change them (viewLocations.Select(path => "/AnotherPath" + path)).
To register your custom view location expander in MVC, add next lines to ConfigureServices method in Startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new MyViewLocationExpander());
});
}
There's actually a lot easier method than hardcoding the paths into your constructor. Below is an example of extending the Razor engine to add new paths. One thing I'm not entirely sure about is whether the paths you add here will be cached:
public class ExtendedRazorViewEngine : RazorViewEngine
{
public void AddViewLocationFormat(string paths)
{
List<string> existingPaths = new List<string>(ViewLocationFormats);
existingPaths.Add(paths);
ViewLocationFormats = existingPaths.ToArray();
}
public void AddPartialViewLocationFormat(string paths)
{
List<string> existingPaths = new List<string>(PartialViewLocationFormats);
existingPaths.Add(paths);
PartialViewLocationFormats = existingPaths.ToArray();
}
}
And your Global.asax.cs
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ExtendedRazorViewEngine engine = new ExtendedRazorViewEngine();
engine.AddViewLocationFormat("~/MyThemes/{1}/{0}.cshtml");
engine.AddViewLocationFormat("~/MyThemes/{1}/{0}.vbhtml");
// Add a shared location too, as the lines above are controller specific
engine.AddPartialViewLocationFormat("~/MyThemes/{0}.cshtml");
engine.AddPartialViewLocationFormat("~/MyThemes/{0}.vbhtml");
ViewEngines.Engines.Add(engine);
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
One thing to note: your custom location will need the ViewStart.cshtml file in its root.
If you want just add new paths, you can add to the default view engines and spare some lines of code:
ViewEngines.Engines.Clear();
var razorEngine = new RazorViewEngine();
razorEngine.MasterLocationFormats = razorEngine.MasterLocationFormats
.Concat(new[] {
"~/custom/path/{0}.cshtml"
}).ToArray();
razorEngine.PartialViewLocationFormats = razorEngine.PartialViewLocationFormats
.Concat(new[] {
"~/custom/path/{1}/{0}.cshtml", // {1} = controller name
"~/custom/path/Shared/{0}.cshtml"
}).ToArray();
ViewEngines.Engines.Add(razorEngine);
The same applies to WebFormEngine
Instead of subclassing the RazorViewEngine, or replacing it outright, you can just alter existing RazorViewEngine's PartialViewLocationFormats property. This code goes in Application_Start:
System.Web.Mvc.RazorViewEngine rve = (RazorViewEngine)ViewEngines.Engines
.Where(e=>e.GetType()==typeof(RazorViewEngine))
.FirstOrDefault();
string[] additionalPartialViewLocations = new[] {
"~/Views/[YourCustomPathHere]"
};
if(rve!=null)
{
rve.PartialViewLocationFormats = rve.PartialViewLocationFormats
.Union( additionalPartialViewLocations )
.ToArray();
}
Last I checked, this requires you to build your own ViewEngine. I don't know if they made it easier in RC1 though.
The basic approach I used before the first RC was, in my own ViewEngine, to split the namespace of the controller and look for folders which matched the parts.
EDIT:
Went back and found the code. Here's the general idea.
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
{
string ns = controllerContext.Controller.GetType().Namespace;
string controller = controllerContext.Controller.GetType().Name.Replace("Controller", "");
//try to find the view
string rel = "~/Views/" +
(
ns == baseControllerNamespace ? "" :
ns.Substring(baseControllerNamespace.Length + 1).Replace(".", "/") + "/"
)
+ controller;
string[] pathsToSearch = new string[]{
rel+"/"+viewName+".aspx",
rel+"/"+viewName+".ascx"
};
string viewPath = null;
foreach (var path in pathsToSearch)
{
if (this.VirtualPathProvider.FileExists(path))
{
viewPath = path;
break;
}
}
if (viewPath != null)
{
string masterPath = null;
//try find the master
if (!string.IsNullOrEmpty(masterName))
{
string[] masterPathsToSearch = new string[]{
rel+"/"+masterName+".master",
"~/Views/"+ controller +"/"+ masterName+".master",
"~/Views/Shared/"+ masterName+".master"
};
foreach (var path in masterPathsToSearch)
{
if (this.VirtualPathProvider.FileExists(path))
{
masterPath = path;
break;
}
}
}
if (string.IsNullOrEmpty(masterName) || masterPath != null)
{
return new ViewEngineResult(
this.CreateView(controllerContext, viewPath, masterPath), this);
}
}
//try default implementation
var result = base.FindView(controllerContext, viewName, masterName);
if (result.View == null)
{
//add the location searched
return new ViewEngineResult(pathsToSearch);
}
return result;
}
Try something like this:
private static void RegisterViewEngines(ICollection<IViewEngine> engines)
{
engines.Add(new WebFormViewEngine
{
MasterLocationFormats = new[] {"~/App/Views/Admin/{0}.master"},
PartialViewLocationFormats = new[] {"~/App/Views/Admin//{1}/{0}.ascx"},
ViewLocationFormats = new[] {"~/App/Views/Admin//{1}/{0}.aspx"}
});
}
protected void Application_Start()
{
RegisterViewEngines(ViewEngines.Engines);
}
Note: for ASP.NET MVC 2 they have additional location paths you will need to set for views in 'Areas'.
AreaViewLocationFormats
AreaPartialViewLocationFormats
AreaMasterLocationFormats
Creating a view engine for an Area is described on Phil's blog.
Note: This is for preview release 1 so is subject to change.
Most of the answers here, clear the existing locations by calling ViewEngines.Engines.Clear() and then add them back in again... there is no need to do this.
We can simply add the new locations to the existing ones, as shown below:
// note that the base class is RazorViewEngine, NOT WebFormViewEngine
public class ExpandedViewEngine : RazorViewEngine
{
public ExpandedViewEngine()
{
var customViewSubfolders = new[]
{
// {1} is conroller name, {0} is action name
"~/Areas/AreaName/Views/Subfolder1/{1}/{0}.cshtml",
"~/Areas/AreaName/Views/Subfolder1/Shared/{0}.cshtml"
};
var customPartialViewSubfolders = new[]
{
"~/Areas/MyAreaName/Views/Subfolder1/{1}/Partials/{0}.cshtml",
"~/Areas/MyAreaName/Views/Subfolder1/Shared/Partials/{0}.cshtml"
};
ViewLocationFormats = ViewLocationFormats.Union(customViewSubfolders).ToArray();
PartialViewLocationFormats = PartialViewLocationFormats.Union(customPartialViewSubfolders).ToArray();
// use the following if you want to extend the master locations
// MasterLocationFormats = MasterLocationFormats.Union(new[] { "new master location" }).ToArray();
}
}
Now you can configure your project to use the above RazorViewEngine in Global.asax:
protected void Application_Start()
{
ViewEngines.Engines.Add(new ExpandedViewEngine());
// more configurations
}
See this tutoral for more info.
I did it this way in MVC 5. I didn't want to clear the default locations.
Helper Class:
namespace ConKit.Helpers
{
public static class AppStartHelper
{
public static void AddConKitViewLocations()
{
// get engine
RazorViewEngine engine = ViewEngines.Engines.OfType<RazorViewEngine>().FirstOrDefault();
if (engine == null)
{
return;
}
// extend view locations
engine.ViewLocationFormats =
engine.ViewLocationFormats.Concat(new string[] {
"~/Views/ConKit/{1}/{0}.cshtml",
"~/Views/ConKit/{0}.cshtml"
}).ToArray();
// extend partial view locations
engine.PartialViewLocationFormats =
engine.PartialViewLocationFormats.Concat(new string[] {
"~/Views/ConKit/{0}.cshtml"
}).ToArray();
}
}
}
And then in Application_Start:
// Add ConKit View locations
ConKit.Helpers.AppStartHelper.AddConKitViewLocations();
i have a class library with class "Customer" having method
public void updateconfirmstatus(int p, int reg_id, int status)
{
CustomerDac.updateconfirmstatus(p, reg_id, status);
}
im using student.aspx
using Myproject.Business;
protected void DoctorDetails_RowUpdating(object sender,GridViewUpdateEventArgs e)
{
Customer customer = new Customer();
}
Eventhough i added library to my project,and my class having method it shows me error like this
Why this happens and how to resolve this...Thank you...
Updated Code:
public static void updateconfirmstatus(int p, int reg_id, int status)
{
//Logic...
}
Using VS2012/.NET 4.5 I am creating a custom activity which implements a Receive child activity (as an implementation child). The parameters are in the example below fixed to just one: OutValue of type Guid.
I really would love to access the value of incoming parameter value in ReceiveDone, because I need to work with it and transform it before returning it from the activity. Please ignore that I am currently using a Guid, it still fails to access the value with and InvalidOperationException:
An Activity can only get the location of arguments which it owns. Activity 'TestActivity' is trying to get the location of argument 'OutValue' which is owned by activity 'Wait for
workflow start request [Internal for TestActivity]'
I have tried everything I could think of, but am stupefied. There must be a way to do this very simple thing?
public class TestActivity : NativeActivity<Guid>
{
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
var content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
// How to access the runtime value of this inside TestActivity?
{"OutValue", new OutArgument<Guid>()}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = content
};
foreach (KeyValuePair<string, OutArgument> keyValuePair in content.Parameters)
{
metadata.AddImportedChild(keyValuePair.Value.Expression);
}
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
var receive = completedInstance.Activity as Receive;
ReceiveParametersContent content = receive.Content as ReceiveParametersContent;
try
{
// This causes InvalidOperationException.
// An Activity can only get the location of arguments which it owns.
// Activity 'TestActivity' is trying to get the location of argument 'OutValue'
// which is owned by activity 'Wait for workflow start request [Internal for TestActivity]'
var parmValue = content.Parameters["OutValue"].Get(context);
}
catch (Exception)
{ }
}
private Receive startReceiver;
private const string Namespace = "http://company.namespace";
}
Use internal variables to pass values between internal activities.
Although not directly related to your code, see the example below which should give you the idea:
public sealed class CustomNativeActivity : NativeActivity<int>
{
private Variable<int> internalVar;
private Assign<int> internalAssign;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
internalVar = new Variable<int>("intInternalVar", 10);
metadata.AddImplementationVariable(internalVar);
internalAssign = new Assign<int>
{
To = internalVar,
Value = 12345
};
metadata.AddImplementationChild(internalAssign);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(internalAssign, (activityContext, instance) =>
{
// Use internalVar value, which was seted by previous activity
var value = internalVar.Get(activityContext);
Result.Set(activityContext, value);
});
}
}
Calling the above activity:
WorkflowInvoker.Invoke<int>(new CustomNativeActivity());
Will output:
12345
Edit:
In your case your OutArgument will be the internalVar
new OutArgument<int>(internalVar);
You need to use OutArgument and them to variables. See the code example with the documentation.
I may have tried everything I thought of, but I am stubborn and refuse to give up, so I kept on thinking ;)
I here have changed my example to use a Data class as a parameter instead (it does not change anything in itself, but I needed that in my real world example).
This code below is now a working example on how to access the incoming data. The use of an implementation Variable is the key:
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
And the OutArgument:
new OutArgument<Data>(runtimeVariable)
I can then access the value with:
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
I haven't seen an example elsewhere, which does exactly this. Hope it will be of use to any one but me.
The code:
[DataContract]
public class Data
{
[DataMember]
Guid Property1 { get; set; }
[DataMember]
int Property2 { get; set; }
}
public class TestActivity : NativeActivity<Guid>
{
public ReceiveContent Content { get; set; }
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
{"OutValue", new OutArgument<Data> (runtimeVariable)}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = Content
};
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
}
private Receive startReceiver;
private Variable<Data> runtimeVariable;
private const string Namespace = "http://company.namespace";
}