We're developing applications for AppExchange and are trying to figure out the best way to do development and release management. There are several issues around this:
1) Package Prefixes. We are developing code in unmanaged mode and releasing as managed, so we have to add all the package prefixes into the code. Is there a way to do this dynamically at runtime? Right now we're using an Ant script, which stops us benefitting from the force.com IDE plugin.
2) Resource files... We are doing some ajax-ey stuff and as a result have a few different resource files we upload, some of which are multiple file resources (zip files). Has anyone automated the building of these resources using ANT, and does that work well?
Our environment seems very fragile and works for some developers and not others; have other people had this problem? How did you resolve it?
I hate to say it, but it sounds like you've settled on the best approach that I know of. The Salesforce packaging environment can be a total nightmare to work with. Once your managed package has a prefix, there's really no going back to a plain package without one unless you script it like you've done. So you'll find the package name peppered throughout your code, which the system will add for you.
I've found the best way to work with it is to keep a "pure" version of your app, which will install cleanly into a dev org from within Ant. Once you have the code in Ant, it can be added into "normal" source control. It doesn't seem like too many larger scale apps have been built in Salesforce with multiple team members, because as far as I can tell, there isn't much support for a workflow that includes source code control. They tried adding some type of release management to a dev org configuration, which is now in beta, but it didn't seem that good at all.
I think Ant using the Salesforce Force.com migration tool is the way to go for the most part. Then, however, once you want to make a managed package, you're sort of stuck with that code base frozen, with that prefix, where you'll then have to do packaging releases (from beta, etc) from within the packaging system itself. The best way there is to refresh to sandbox (hard limit of once a month!!), then have developers pull out of that sandbox and deploy into individual dev orgs, which then can be merged periodically into a "group dev org", before deploying back into the Sandbox (using Force.com IDE or Ant), then into Production.
The whole process is basically a complete disaster. Salesforce is so close to having a super powerful platform, but a lot of the time feels like an awesome sports car without a steering wheel.
As far as static resources, those you should be able to automate in a relatively straightforward way using Eclipse, so that you can deploy those separately in one step. The API should support it, too.
I have worked on some rather large Apex code bases (I think, and hope), and there is really no apparent elegant solution, I'm afraid. You'll be stuck with strange combinations of deploying using Ant in some cases, Eclipse others, etc.
Coming from other development environments, it's often befuddling and just strange. For example, it's perplexing that you can't easily dump the database in one step while keeping track of relationships between objects and then "import" it into another org in one step. We actually had to write a tool that would make it easy to extract all data while traversing object relationships, load all data, recursively delete data, etc. from a xls file because we needed an easy way to test in orgs.
BTW, dev orgs are basically throw away orgs. We create dozens of them for different testing purposes and to keep different versions and configurations.
Sorry I couldn't give you better news. There might be more of a guru on here who can point to an elegant way to manage packaging, and I'll be as interested in you as the answer! You can email me at suprasphere --- at --- gmail if you want to commiserate! :)
We've recently switched to using a Prefix Manager instead of doing ant substitutions.
Here is our code.
public class PrefixMgr {
private static string objPrefix = null;
public static string getObjPrefix() {
if(objPrefix == null) {
try {
Database.query( 'select MyColumn__c from my_prefix__MySmallTable__c' );
objPrefix = 'my_prefix__';
}
catch(Exception e) {
objPrefix = '';
}
}
return objPrefix;
}
public static string getAppPrefix() {
return 'my_prefix__';
}
public static string getObjName(string inp) {
return getObjPrefix() + inp;
}
}
Basically this attempts a query (one time) against a table with the prefixed name. If it does not exist, then we are in unmanaged mode with no package prefixes. If it does succeed, then we set the prefix appropriately. getObjName is a convenience because PrefixMgr.getObjName('MyObject__c') is easier to read (esp in a string concat) than PrefixMgr.getObjPrefix() + 'MyObject__c'.
Interested in thoughts and comments.
Related
I've been trying to both convert old code and write new code using GetScopedService().
However, I keep discovering ones I didn't know about.
Is there an easy way to find the complete list of services available for 2sxc? For DNN? And maybe even RazorBlade?
If they are not documented somewhere, is there a page of code in the public repositories that I could bookmark where it would be easy to see (and compile) a list of them?
Your best place to start is https://r.2sxc.org/services (which goes to https://docs.2sxc.org/api/dot-net/ToSic.Sxc.Services.html)
This is where we keep all the current services published. Other services are to be seen as exotic / rare use.
Razor-Blade is still mostly non-service, but we plan to fix that.
We're just about to release ServiceKits as a feature, which would make things even more intuitive. For example, ServiceKit14 has all commonly used services on it, and also IScrub from Razor Blade.
We're designing a system for a client where they are allowing authenticated users to upload images. We've created an API to upload the files but the client only wants the latest file and delete all previous ones so that there would only ever be one.
We've looked through the docs and can't come across a way for ADAM to handle this in both 2SXC and DNN's file system.
Internally when deleting images we see API calls like the following to the internal 2SXC API, but we're wondering if this is exposed somewhere within the public API?
https://somedomain.com/api/2sxc/app/auto/data/61393528-b401-411f-a001-f423ea46700a/b7d04e2c-c565-496c-8efb-aa133cf90d33/Photo/delete?subfolder=&isFolder=false&id=189&usePortalRoot=false&appId=3
We could probably use the same endpoint above, but we'd likely run into permission issues or changes to the APIs that could be problematic.
Thank you for any advice you can give! Perhaps #iJungleBoy can provide some thoughts on this.
As a solution from a completely different direction, if you are on the later release of 2sxc (v12.8+, v13+), and comfortable programming in C#, you might consider doing this as a "cleanup" from a Dnn Scheduled Task. This can be done with a relatively easy setup. We have a Gist in place that we use as a starter. You simply put the code in the /App_Code folder then setup a normal Dnn Scheduled Task. NOTE that you can scroll down to the first comment on the Gist to see a screenshot of a complete working setup.
Accuraty's AccuTasks template on GitHub Gists
There are two more key things to note:
You need to install Dnn's CodeDom 3.6 because the example uses the later versions C#'s string interpolation - OR remove the few $"ASL2021 - {this.GetType().Name}, Task Scheduled Email", bits or convert to string.Format() or something.
Since your task's code is NOT running in a (2sxc) module, if needed, you'll do stuff like this: 2sxc Docs - Use 2sxc Instance or App Data from External C# Code
So, if you are comfortable writing code that "finds and deletes stuff older than NN days" - this might be the way to go.
Is there any way in Salesforce to group apex classes under a package or namespace? Can we use managed package for internal organization purpose?
This is a limitation in the force.com stack that makes medium-large size projects painful, if not impractical. Using managed packages in order to get a package prefix doesn't really solve any problems, so it's not really worth the trouble.
I usually try to organize a project into one flat level of namespaces. In lieu of actual namespaces, I'll give each would-be-namespace a 3-5 character name, to be used as a prefix. Any class that belongs in the "namespace" gets prefixed. E.g., if I need a payroll namespace, I'd use a PYRL prefix. A class called PaycheckCalculator becomes PYRL_PaycheckCalculator.
The practical advantage of this type of convention is it helps prevent name clashes and classes are grouped by their "namespace" when viewed in a sorted list, such as in an IDE, or Setup > Develop > Apex Classes
Unfortunately, several basic OO principles are still fundamentally broken. Probably the most important one is every class forms an implicit dependency on every other class it has visibility to, which is all of them.
I'd love to hear how others have worked around this limitation.
Well, you can use managed packages, but as Jeremy mentioned it doesn't really buy you much. Of course managed packages are essential for developing publicly listed apps to sell on the AppExchange. But internally it's really an org-wide problem since once you create a managed package with a prefix, everything that touches any other part of it gets stamped with the same namespace prefix, including all custom objects. And worse, you can't access code in a managed package from outside the managed package (which is actually the whole point of them in the first place).
Although it's not the prettiest solution, what I personally do is maintain numerous named orgs with different purposes, applications and utility classes. When I need a utility class in one org, say I'm building a new app destined for the AppExchange, I'll do an Eclipse Export/Import from the utility org in question. It definitely seems strange but having a library of orgs is the best way I've managed to keep track of everything and to manage "internal" organization. But the end result is really just a glorified copy-paste operation between arbitrary code stores.
I faced similar challenges while working on big projects, wrote this blog post sometime back to share the approach I am following now : http://www.tgerm.com/2011/11/apex-class-naming-convention-suggestion.html
I would like to extend my WinForms app, which a feature that allows me to monitor which functions are used by the users.
The idea is to count how many times e.g. a button has been clicked, or a popup was opened.
I want to know which features are used more or less often by the users.
Any ideas how this can be done? (Or even if somebody solved this problem already)
tia,
Martin
The only mechanism I can think on to do what your looking for is to use a logger like log4net / Log4PostSharp to log details to a log file on the machine, this would give you details on usage for that particular client. You would have to create a custom attribute that you could decorate your methods with that would result in something being written out to the log file, otherwise your code would end up littered with code to implement the logging!
Have a look at this article too, it uses Log4PostSharp with AOP (Aspect Oriented Programming) which would make the implementation of the logging much more cleaner (uses attributes).
http://www.codeproject.com/KB/dotnet/log4postsharp-intro.aspx
You can find some if you google for the term "application analytics" instead of "feature tracking".
I have found the following products:
includeapp.com
Software Statistics Service
Dotfuscator for .NET, DashO for Java
FusionAnalytics
Flurry Analytics
OpenSpan Desktop Analytics
DeskMetrics
EQATEC Analytics
Rapidengines
I might say that I also plan to create such a product. When it will be Beta I will add it to the list.
I know it has great out-of-the-box features but is it easy to customize?
Like when I query stuff from the database or change css layouts.
Is it faster to create my own modules for it or just go on and write everything from scratch using frameworks like Cake
I'm currently working on an Elgg-based site and I absolutely hate it. The project was near completion when I stepped in, but the people who created were no longer available, so I took it over as a freelancer.
As a personal impression, you are much better off writing the app from scratch in a framework. I don't know if the people before me butchered it, but the code looks awful, the entity-based relationship model is wierd to say the least and debugging is horrendous. Also, from my point of view, it doesn't scale very well. If you were to have a consistent user base, I'd be really really worried.
It keeps two global objects ($vars and $CONFIG) that have more than 5000(!) members loaded in memory on each page. This is a crap indicator.
I've worked extensively with cake. With Elgg, for about a month in a project that is on QA stage right now.
My advise is: if you need something quick with a lot of features and you only need to customize a little, go with Elgg.
If you're going to customize a lot and you can afford the development of all the forums, friends, invites, etc. features, go with Cake or any other MVC framework.
I have been working on a Elgg site for the past month or so, its code is horrible, however it's not the worst I've seen :D. it's not built for programmers like Drupal is :D. But it's not too bad. Once I got a handle on the metadata functions and read most of the code I was able to navigate it well and create custom modules and such.
What would help immensely would be some real documentation and explanation of the Elgg system. I don't think that's going to happen though :).
Out of the box there are a few problems, there are some bugs that haven't been fixed for a while and I've had to go in and fix them myself. Overall, you can make it pretty and it has some cool functions, but i wouldn't dive in until i had read the main core code to get a handle on what's happening on the backend.
Oh and massive use of storing values in globals. and a crap ton of DB calls (same with Drupal though).
i wonder if the use of storing everything, and i mean everything for your site in the globals will really hinder the server if you have a massive user load.
If you want to build a product based on a social networking platform/framework then Elgg is definately a good way to go. The code is not that bad if you actually look before leaping and doing what elgg expects. You go against its processes and structures and it will leave you beaten by the side of the road.
Developing modules/plugins or editing CSS is easy and Elgg does give you great flexability to basically build your own product ontop of it. Dolphin, as comparrison, does not allow you to do anything outside of what it expects you to do.
If you however just need a framework (not primarily for social networking etc) with some user based functionality then i suggest Cake, or if your project is HUGE then maybe Symfony or Zend. They all have plugins you can download and use/hack which would be easirer to adjust for personalised needs.
To show what you can do with elgg here is a site Mobilitate we built with Elgg 1.7. This is a very complicated website and was built ontop of Elgg.
We are starting a new project with Elgg 1.8. The new version is a major improvement they have made a lot of elements easier, incorporated better JS and CSS implementation/structure and have better commented their own code.
Elgg's database schema is horrific. They've essentially implemented a NoSQL database in SQL. It completely defeats the purpose of using a relational table structure.
If you can ignore this, and aren't doing much customization, you might be OK with Elgg. If not, STAY AWAY.
I've been working with Elgg for over a year. It is easier to customize than it would be to build something from scratch using a framework like CakePHP. I tried CakePHP and found it even more complicated than Elgg.
It is difficult to query the database due to the entity-based relationship model. You should use the build-in methods for accessing data. However, I have written many queries to double check on what is actually stored in the database.
You cannot change layouts using CSS alone. You have to deal with the various Elgg views. But CakePHP uses the same Model/View/Controller MVC concept so that would be just as difficult.