These warnings will become errors in the future

Does IceContext work for you? This is what I’ve been using for years, no warnings on this yet.

using (var txScope = IceContext.CreateDefaultTransactionScope()) 
{
    // code here
    Db.Validate();
    txScope.Complete();
}

Edit:

Oops or I should say simply passing in Db

using (var ud100svc = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.UD100SvcContract>(Db))

That doesn’t compile in a function. Or maybe I am just doing it wrong.

In a Function we use this.CallService

Example 1

this.CallService<Ice.Contracts.DynamicQuerySvcContract>(boDynamicQuery =>
{
    dsDynamicQuery = boDynamicQuery.ExecuteByID(pBaqID, dsQueryExecution);
});

Example 2

this.CallService<InventoryQtyAdjSvcContract>(invQtyAdj =>
{

    var invDS = invQtyAdj.GetInventoryQtyAdj(iPartNum, string.Empty);
    foreach (var ttInventoryQtyAdj in invDS.InventoryQtyAdj)
    {
      ttInventoryQtyAdj.WareHseCode = iWhse;
      ttInventoryQtyAdj.BinNum = iBinNum;
      ttInventoryQtyAdj.LotNum = iLotNum;
      ttInventoryQtyAdj.AdjustQuantity = iQty;
      ttInventoryQtyAdj.Reference = (string.IsNullOrEmpty(iRef) ? "EFX ADJ" : iRef);
      ttInventoryQtyAdj.AllowNegQty = false;
      ttInventoryQtyAdj.ReasonCode = iReason;
      ttInventoryQtyAdj.ReasonCodeDescription = Db.Reason.Where(x => x.Company == Session.CompanyID && x.ReasonCode == iReason).Select(x => x.Description).FirstOrDefault();
      ttInventoryQtyAdj.TransDate = (iTranDate == null ? DateTime.Today : iTranDate);
      ttInventoryQtyAdj.RowMod = "U";
    }
    string NegQtyAction, pcMsg;
    invQtyAdj.NegativeInventoryTest(iPartNum, iWhse, iBinNum, iLotNum, 0, "", iDimCode, 1, iQty, out NegQtyAction, out pcMsg);
    // etc...
});
3 Likes

That looks like its calling a BAQ though?

The first one calls a BAQ the second one is Inv Adjustment both use CallService.

That’s a standard c# compiler error I think, not a special Epicor one

I think its just warning you that you haven’t disposed of something as far as it can tell and so may have a memory leak.

Heres another example

// Time Types to Auto Approve
var autoApprovedTimeTypes = new List<string> { "HOLIDAY" };

this.CallService<LaborSvcContract>(lbr => {
  // Create the time record
  LaborTableset ts = new LaborTableset();
  lbr.GetNewLaborHed1(ref ts, iEmpID, false, iDateTime);
  
  // Set out time based on input
  var hrsDuration = (iMinDuration / 60.00M);
  var newOutTime = ts.LaborHed[0].ClockInTime + hrsDuration;
  ts.LaborHed[0].ClockOutTime = newOutTime;
  ts.LaborHed[0].ActualClockOutTime = newOutTime;
  lbr.DefaultTime(ref ts, "ClockOutTime", newOutTime);
   
  // Make additional updates
  ts.LaborHed[0].FeedPayroll = true;  
  ts.LaborHed[0].SetUDField<string>("Character01", iTimeType);
  ts.LaborHed[0].SetUDField<bool>("ExclFromWkndPremium_c", iExcludeWkndPremium);
  ts.LaborHed[0].TranSet = "AtmEntry";
  
  // Set Disposition to Approved if TimeType is in Auto Approved List
  if (autoApprovedTimeTypes.Contains(iTimeType, StringComparer.OrdinalIgnoreCase))
  {
    ts.LaborHed[0].SetUDField<string>("TODisposition_c", "APPROVED");
  }
  
  lbr.Update(ref ts);
  ts = null;
});
2 Likes

Oh! Using this.CallService compiles without the warnings that will become errors message, thank you!

2 Likes

@Haso… Auto Approve Holidays… can I come and work for you guys :slight_smile:

Leave Approved GIF

In all seriousness, if there is going to be some “lockdown” or conversion to exceptions down the track, please please please, at least do the following:

  • Provide a timeframe for when this is going to occur so we have plenty of time to clean things up.
  • Provide a Warnings and Error Cookbook that is available for us to work through what the Epicor suggested options/replacements are…

It would be nice to say we have all the time in the world to investigate this ourselves, but the truth is we are as time poor as the next person, if not more, users after us, constant change if you are on cloud and then all of a sudden wammo a another thing starts to pull the rug from under our feet, and good old System.IO stops working from some magical reason…

Thanks… This is not a dig but a plea for better transparency around these sorts of things.

6 Likes

That one is a good one actually.

It reminds you to dispose if your objects that implement the idisposable interface.

You can do 1 of three things.

  • Call dispose on the object when you are done with it.
  • Wrap the call in a using block, which will call dispose for you when it goes out of scope
  • Restructure to use callservice like @hkeric.wci said

Callservive is a nice syntactic sugar method that combines creating the object as well as disposing it for you.

We also have CallLibrary which I can explain later if you’d like.

4 Likes

Also, one of the purposes of CallService was to work with the improved security model of functions.

Functions have a special Db context that allows granular control of what you can and can’t access in the Db.

By creating your own context, you are bypassing that security model.

—-
Note, even though in BPMs and UBAQs (personal BPMs lol) you have access to an inbuilt Db Context, CallService is available there for use as well if you want to have a consistent approach to code.

7 Likes

This should resolve your context error.

using (var context = Ice.Services.ContextFactory.CreateContext())
{
// Code here …
}

1 Like

I guess never noticed it, since we use using pretty much for anything. :slight_smile:

1 Like

I think that may be a bug.

Epicor might have forgotten to insert

INSERT INTO Ice.SysConfig (Key1, Key2, SysCharacter01)
VALUES (N'CustomCodeAnalysis', N'Enabled', 'false');

Its neither true or false (the row doesnt exist) which will cause their flag = !bool.TryParse((string)obj, ref enabled) || enabled; to return true, maybe something that needs to be added to the upgrade process @Rich @Epic_Santiago - worked for me on-prem.


To give you an idea what Custom Code Analyzer tries to restrict

6 Likes

What a flex :muscle:

4 Likes

Hi everyone. There will be a more formal announcement under the Epicor Ideas portal. But since this subject continues to be a very hot topic (and I continue to be tagged :slight_smile:), I can share that with 2024.2 we have a new Sandbox class available in custom code. This class will continue evolving to provide safe solutions to some of the common but problematic code patterns we’ve identified. In this release, the theme is IO. You will find under Sandbox, equivalents of your favourite methods under System.IO. They will look almost identical with the difference that instead of passing an arbitrary path, you will be passing a path class that allows you access to relevant parts of server. This provides both safety as well as abstracting the filesystem so you don’t have to hardcode paths or try to figure out where things are. The same class will be available in the different flavours of custom code such as Functions, Data Directives and Method Directives.

And now, to dispel some FUD, I want to clarify that there’s no conspiracy to stop supporting customization and instead drive revenue to CSG. We continue to invest in our customization subsystem as it is one of the key features of Kinetic.

Code that we’ve marked as problematic is based on data from a combination of upgrading thousands of customers every year, performing regular security scans and many many support tickets. For example, the Dispose warning above is the cause of many customer down incidents as custom code consumes all SQL connections after running enough times without disposing of them.

So reigning in problematic patterns in custom code is here to stay. Whenever possible, we will be providing safe alternatives in the new Sandbox class. But certain things we don’t plan to support. Reflection for example is used to access things that are not part of the public API. As such, it makes for brittle code that will break on upgrade. If there’s something not public that you need access to, please create a support ticket or an Epicor Idea. Also, the CustomCodeAnalysis setting mentioned above was just a temporary setting while we introduced code analysis. Don’t rely on that as the solution as it is not long for this world.

14 Likes

I’m sorry, but reflection is a standard part of coding today, and is the only way to do anything truly advanced inside Epicor. Being able to enumerate types and dig in deep lets us bring Epicor places only dreamed of, at least not without significant extra time investment and workarounds.

Can you do things unorthodox or dangerous with it? Of course you can. I can also bring the system to its knees or destroy it completely with code that is sanctioned and A-OK as well. A distinction without a difference I would think.

If someone uses code that is bad, that’s on them, not Epicor. Tell the customer that, not take our tooling away.

I believe Epicor should focus their time and energy on expanding our toolset, not throwing up roadblocks.

10 Likes

This needs to be done with far more transparency about exactly what restrictions will be implemented and when they will take effect.

8 Likes

@Epic_Santiago Thanks for the clarification and for breaking down the reasoning behind these restrictions. I totally get why Epicor is locking down some of these risky code patterns, especially with the focus on keeping things stable in SaaS. As much as it breaks my heart to admit it, let’s be real, giving untethered access to stuff that can crash the system isn’t great for anyone. The new Sandbox class sounds like a smart move to keep the functionality we need without opening Pandora’s box.

@klincecum, I’m with you on the fact that Reflection and IO access let us push Epicor to places beyond what the standard APIs can do. Yeah, losing that flexibility stings, and I’ll definitely miss it too. But we also have to remember that Reflection wasn’t ever really supported, and as awesome as you are at using it right, there’s always that risk of someone less experienced using it to wreck the whole environment. I mean, Spiderman Rules, right? :smile:

Epicor’s balancing act between flexibility and platform security isn’t easy, but I think they’re doing a solid job by giving us ample warnings and sandboxed alternatives to work with.

I’m optimistic that we can keep pushing innovation without compromising the platform. And let’s not forget how big it is that @Epic_Santiago is here, listening, explaining, and taking our feedback. They’re hearing us! But we’ve gotta be fair with our asks because let’s face it, not everyone is a @klincecum. Some folks have the same power with a lot less experience!

And yes we are all special in our own way… I’ve been asking for years to get access to their Git Repo so I can do some PRs :rofl:… chop chop Santiago! make it so :rofl::rofl: #FreeLabor :man_shrugging:

9 Likes