Storing a reference to an object to be - c#-4.0

I don't know if this is possible at all so this is a shot in the dark.
Anyhow...
Consider having the following model:
Class Model
{
public List<string> TheList = null;
}
The List is set to null on purpose.
var model = new Model();
command.RegisterInData( model => model.TheList ); // TheList is null at this point
model.TheList = new List<string>();
model.TheList.Add("A value here");
command.Execute(); // <-- Here I want to access the new list somehow
As said, I don't know if anything like this is possible but I would like a push in the right direction.
The function desired: I would like to tell the command where to put the result before I have a concrete object.
Thanks in advance

This seems quite doable. Here is a variation with an even simpler accessor:
class Command
{
private Func<List<string>> listAccessor;
public void RegisterInData(Func<List<string>> listAccessor)
{
this.listAccessor = listAccessor;
}
public void Execute()
{
var list = this.listAccessor();
foreach (string s in list)
{
Console.Log(s);
}
}
}
// Elsewhere
var model = new Model();
command.RegisterInData(() => model.TheList);
model.TheList = new List<string>();
model.TheList.Add("A value here");
command.Execute();
You'll probably want error handling for the case where RegisterInData is not called before Execute, but you get the idea.

You simply have to delay calling the delegate passed to RegisterInData and call it (I guess) at Execute.

Could Lazy be of use here? http://msdn.microsoft.com/en-us/library/dd642331.aspx

Related

Why am I getting blank records when using PXDatabase.GetSlot to retrieve data from a table?

I set up this IPrefetchable class because I needed to store a set of data in memory for quick access to it and wanted it returned as a dictionary. I'm using PXDatabase.GetSlot to save data from INItemLotSerial into a pxdatabase slot, however when dbRecords selects the records from it, the field values in it are null(lotserialnbr, inventoryID, etc) although it does return the correct count of records. This is my first time using PXDatabase.GetSlot so perhaps I'm missing something fairly simple.
Any suggestions would be greatly appreciated. Thank you.
class INItemLotSerialFetcher : IPrefetchable
{
private Dictionary<string, int?> _availlist = new Dictionary<string, int?>();
public void Prefetch()
{
// read database
var dbRecords = PXDatabase.Select<INItemLotSerial>();
//add results to Dictionary
foreach (var rec in dbRecords)
{
if (rec.LotSerialNbr != null)
{
_availlist.Add(rec.LotSerialNbr, rec.InventoryID);
}
}
}
public static Dictionary<string, int?> GetINList()
{
var def = GetSlot();
return def._availlist;
}
private static INItemLotSerialFetcher GetSlot()
{
return PXDatabase.GetSlot<INItemLotSerialFetcher>("INserialFetcherSlot", typeof(INItemLotSerial));
}
}
Try this change ala an example from Sergey Marenich
public static Dictionary<string, int?> GetINList()
{
return PXDatabase.GetSlot<INItemLotSerialFetcher>("INserialFetcherSlot", typeof(INItemLotSerial));
}

Release invoice on new screen

I need your help.
I have created a new screen, where I am calling all invoices pending release.
I have problems to release, I send a message where you request (you want to release).
It shows me the infinite message.
Only once should you ask me, then you should go out and follow the normal process.
public ProcessDocNew()
{
// Acuminator disable once PX1008 LongOperationDelegateSynchronousExecution [Justification]
Document.SetProcessDelegate(
delegate (List<ARInvoice> list)
{
List<ARRegister> newlist = new List<ARRegister>(list.Count);
foreach (ARInvoice doc in list)
{
newlist.Add(doc);
}
ProcessDoc(newlist, true);
}
);
Document.SetProcessCaption(ActionsMensje.Process);
Document.SetProcessAllCaption(ActionsMensje.ProcessAll);
}
public virtual void ProcessDoc(List<ARRegister> list, bool isMassProcess)
{
string title = "Test";
string sms = "¿Stamp?";
var Graph = PXGraph.CreateInstance<ARInvoiceEntry>();
ARInvoice document = Document.Current;
PEFEStampDocument timbrar = new PEFEStampDocument();/*This is a class where it is, all my method*/
if (isMassProcess == true)
{
Document.Ask(title, sms, MessageButtons.YesNo, MessageIcon.Question);
{
PXLongOperation.StartOperation(Graph, delegate
{
timbrar.Stamp(document, Graph); /*here I have my release method*/
});
}
}
}
public static class ActionsMensje
{
public const string Process = "Process";
public const string ProcessAll = "Process All";
}
I await your comments
Only once should you ask me, then you should go out and follow the
normal process.
That is not how the processing pattern works. The process delegate is called for each record and is therefore not a valid location to display a message that should be shown only once.
You would need to add a custom action to achieve that behavior. The scenario you're looking for should be implemented with a processing filter checkbox and processing filter to comply with best practices:
Documentation on processing screens implementation is available here:
https://help-2019r2.acumatica.com/Help?ScreenId=ShowWiki&pageid=a007b57b-af69-4c0f-9fd1-f5d98351035f

How to Return Null value from method using FakeItEasy

I have a service faked using FakeitEasy and i am trying to call its method. Here is the Code
var client = container.Resolve<MyService>();
A.CallTo(() => client.GetUserProfile(userName)).Returns(null);
The method GetUserProfile returns some object in actual implementation. but for some reason i want this method to return null. I am using above code to acomplish this purpose but its returning Fake object instead of null.
Here is the Test Setup i am using
[Test]
public void MyTest(string sitecollectionGuid, string customerName)
{
var mockHttpContext = SetupHttpContext(sitecollectionGuid, customerName);
var client = container.Resolve<MyService>();
A.CallTo(() => client.GetUserProfile(userName)).Returns(null);
var controllerContext = new ControllerContext(mockHttpContext, new RouteData(), A.Fake<ControllerBase>());
controller.ControllerContext = controllerContext;
var result = controller.CheckUsername(userName);
Assert.IsNotNull(result, "Result is not as expected");
}
Production Method looks like the following
public UserDAO GetUserProfile(string userName)
{
UserDAO objUserProfile = new UserDAO();
IUsers objUsers = (IUsers)Global.Container["Users"];
IUser objUser = objUsers.GetByUserName(userName);
if (objUser == null)
{
return null;
}
else
{
objUserProfile = AutoMapper.Mapper.Map<IUser, UserDAO>(objUser);
objUserProfile.FirstName = objUser.FirstName;
objUserProfile.MiddleName = objUser.MiddleName;
objUserProfile.LastName = objUser.LastName;
....................
....................
<setting other properties>
....................
....................
return objUserProfile;
}
}
Any help will be appreciated
Thanks
Try and type your (null) reference.
UserDAO returnValue = null;
var client = container.Resolve<MyService>();
A.CallTo(() => client.GetUserProfile(userName)).Returns(returnValue);
In order to configure a method, it has to be virtual, abstract, or defined on an interface that you're faking. However,
public UserDAO GetUserProfile(string userName)
is neither virtual nor abstract, so unless you're creating a fake from an interface, this will not work. However, A.CallTo will raise an error when trying to configure either a non-virtual method or a method on a concrete (not faked) object, and you've not mentioned either of these things happening.
From your code, we still can't tell
where client came from (I know, the container, but how did it get there?),
whether controller uses the same client, and
what the connection between controller.CheckUsername and client.GetUserProfile is
My guesses at this point are
whatever controller is using to CheckUsername, it's not the same client that the test has, or
client.GetUserProfile is being called with the wrong userName (although you use the same one in controller.CheckUsername(userName), so that seems less likely)
If you're unable or unwilling to connect the dots, I suggest checking the value of userName at all points, and making sure that when client is called in the production code, it's a faked object (debug in and examine the type—it should be clear whether its your type or the faked one).
or you could just cast the null to the type in context.
var client = container.Resolve<MyService>();
A.CallTo(() => client.GetUserProfile(userName)).Returns((UserDAO) returnValue);

Display a specific result using foreach in Dictionary C#

Problem that I'm unable to solve is that when I search a contact, if found than I need that contact to be the only output but it's displaying whole record. What should I do?
here is my code
namespace Telephone_Directory
{
class Program
{
public bool info()
{
Console.WriteLine("ENTER THE NAME TO BE SEARCHED");
Dictionary<string, uint> contact = new Dictionary<string, uint>();
contact.Add("usman", 03453648729);
contact.Add("Iqtiqa", 03159825052);
contact.Add("Aamir", 03343315412);
contact.Add("Ghous", 03323142783);
var items = from pair in contact
orderby pair.Value ascending
select pair;
string chk = Console.ReadLine();
if (contact.ContainsKey(chk))
{
foreach (KeyValuePair<string, uint> pair in contact)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
} return true;
}
else
return false;
}
static void Main(string[] args)
{
Program ob =new Program();
bool a=ob.info();
if (a == true)
{
Console.WriteLine("Your contact is found successfully");
}
else
Console.WriteLine("Not found");
Console.ReadLine();
}
}
}
You are checking if the Contact is available but you are iterating over the whole collection as an output. So you can completely remove the first query (var item = ...) because it does not have any effect because you are not using it anywhere.
I would propose accessing everything directly by the Dictionary Key like this
uint srchNumber;
contact.TryGetValue(chk, out srchNumber);
if (srchNumber != null)
Console.WriteLine("{0}: {1}", chk, srchNumber);
this will get you what you want.
But I would suggest to change the implementation because a Dictionary may be not optimal if you will have multiple items with the same name because it only allows you to have every key once. Instead I would suggest to use something like SortedList> or List<...>. Then you may query all possible results with a LINQ-Statement like
var results = from c in contact select c where c.key == chk
this will get you all Key-Value-Pairs belonging to a certain name.
But it is a matter of what you are trying to achieve.

Need help in Sharepoint workflow

I am new to sharepoint development and i have task in hand to do. I need to add few lines of code for the following logic.
Need to check if previous title and new title of task items are same.
If Not, then query the Task list
Find all the items which contain the previous title
Update their titles.
Here is my Pseudocode:
public override void ItemUpdating(SPItemEventProperties properties)
{
try {
this.DisableEventFiring();
//Need to write my logic here
base.ItemUpdating(properties);
}
catch (Exception ex) {
}
finally {
this.EnableEventFiring();
}
}
Can somebody guide me how to write the code for the above mentioned logic? If you have any sample code's with similar logic, please share it. It will be helpful for me.
Thanks in Advance!
This code might help you out. Maybe you need to adapt it for your needs, but the properties you need to access are the same.
public override void ItemUpdating(SPItemEventProperties properties)
{
//this will get your title before updating
var oldName = properties.ListItem["Title"].ToString();
//and this will get the new title
var newName = properties.AfterProperties["Title"].ToString();
if (newName != oldName)
{
using (var site = new SPSite("http://yoursitename"))
using (var web = site.OpenWeb())
{
var list = web.Lists["Tasks"];
var items = list.Items.OfType<SPListItem>().Where(i => (string) i["Title"] == oldName);
foreach (var item in items)
{
item["Title"] = newName;
item.Update();
}
}
}
base.ItemUpdating(properties);
}

Resources