I have finally managed to persuade my nephew to start blogging about the stuff he is doing - reversing games, cheating and thus owning me totally those few times we do sit down and play together.
It is a good posting in my opinion
#!/usr/bin/php <?php /** * You must install * * yum install php-pear * pecl install apd * * and enabled in the php.ini file * * [Zend] * zend_extension = /usr/lib/php/modules/apd.so * * for this to work */ //make sure we dump the stuff to stderr ini_set("error_log","php://stderr"); $svnExportDir='/mnt/'; $siteInstalledVersionStateFilesDir='/mnt/'; $svnPackages = array ( // Define your packages here and the full SVN url 'mypackage' => 'https://XXX/svn/mypackage/trunk', 'mypackage2' => 'https://XXX/svn/mypackage2/trunk', ); $preInstallFunctions = array ( // If your package are using pre_install hooks and you are installing multiple packages and the pre_install hooks contain the same functions // then you need to define them here. This is hack, if the pre_install functions was defined in a class then we could just unset the class. "pre_install", ); $postInstallFunctions = array ( // If your package are using post_install hooks and you are installing multiple packages and the pre_install hooks contain the same functions // then you need to define them here. This is hack, if the post_install functions was defined in a class then we could just unset the class. "post_install", ); $sugarcrmInstallationsToUpdate = array ( 0 => array( 'name' => 'SugarCrmInstallation1 (staging)', 'sugarInstallDir' => '/var/www/sites/staging', 'packagesToUpdate' => array ( 0 => 'mypackage', 1 => 'mypackage2', ), ), ); //initialize if(!defined('sugarEntry')) define('sugarEntry', true); // If you are updating more than one installation there is no need to do the svn export more than one time per // package, just reuse that already downloaded/exported package $packageDownloadedFromSvnRevisionLog = $siteInstalledVersionStateFilesDir . 'ci_packageDownloadedFromSvnRevision.log'; $packageVersionsDownloaded = getArrayFromFile($packageDownloadedFromSvnRevisionLog); foreach($sugarcrmInstallationsToUpdate as $sugarCrmSite){ chdir($sugarCrmSite['sugarInstallDir']); require_once('include/entryPoint.php'); require_once('ModuleInstall/ModuleInstaller.php'); $current_user = new User(); $current_user->is_admin = '1'; $siteInstalledVersionsStateFile = $siteInstalledVersionStateFilesDir . $sugarCrmSite['name'] . '_version'; $revisionNumberInstalledInSite = getArrayFromFile($siteInstalledVersionsStateFile); foreach($sugarCrmSite['packagesToUpdate'] as $key=>$package){ $packageRevisionInstalled = array_key_exists($package, $revisionNumberInstalledInSite) ? $revisionNumberInstalledInSite[$package] : 0; ciLog ("Checking for newer versions in svn ...\n", $sugarCrmSite['name'],$package); $packageRevisionInSvn = trim(`svn info --non-interactive --username YOUR_SVN_USERNAME --password YOUR_SVN_PASSWORD $svnPackages[$package] | grep 'Last Changed Rev' | head -1 | grep -Eo "[0-9]+"`); if ($packageRevisionInstalled < $packageRevisionInSvn) { ciLog ("There are updates in SVN (installed: $packageRevisionInstalled, svn: $packageRevisionInSvn).\n", $sugarCrmSite['name'],$package); $packageRevisionPreviouslyDownloaded = array_key_exists($package, $packageVersionsDownloaded) ? $packageVersionsDownloaded[$package] : 0; if ($packageRevisionPreviouslyDownloaded < $packageRevisionInSvn){ ciLog ("Getting latest version from svn ...\n", $sugarCrmSite['name'],$package); $output = `svn export --force --non-interactive --username YOUR_SVN_USERNAME --password YOUR_SVN_PASSWORD $svnPackages[$package] $svnExportDir$package`; $packageVersionsDownloaded[$package] = $packageRevisionInSvn; saveArrayToFile($packageDownloadedFromSvnRevisionLog, $packageVersionsDownloaded); } else { ciLog ("(rev $packageRevisionInSvn) has previously been downloaded, using local version.\n", $sugarCrmSite['name'],$package); } //initialize the module installer $modInstaller = new ModuleInstaller(); $modInstaller->silent = true; //shuts up the javscript progress bar //start installation ciLog ("(rev $packageRevisionInSvn) Starting installation into " . $sugarCrmSite['sugarInstallDir'] . " ... \n", $sugarCrmSite['name'],$package); $preInstallFile = "$svnExportDir$package/scripts/pre_install.php"; if(is_file($preInstallFile)) { ciLog ("Including $preInstallFile.\n", $sugarCrmSite['name'],$package); include($preInstallFile); ciLog ("Executing $preInstallFile.\n", $sugarCrmSite['name'],$package); pre_install(); // Undeclaring the pre_install functions so we can include the next pre_install file. Nasty, this is a hack. Requires PECL ADP undeclareFunctions($preInstallFunctions); } $modInstaller->install($svnExportDir.$package); $postInstallFile = "$svnExportDir$package/scripts/post_install.php"; if(is_file($postInstallFile)) { $_REQUEST['unzip_dir'] = "$svnExportDir$package"; ciLog ("Including $postInstallFile.\n", $sugarCrmSite['name'],$package); include($postInstallFile); ciLog ("Executing $postInstallFile.\n", $sugarCrmSite['name'],$package); post_install(); // Undeclaring the post_install functions so we can include the next pre_install file. Nasty, this is a hack. Requires PECL ADP undeclareFunctions($postInstallFunctions); } ciLog ("(rev $packageRevisionInSvn) Installation into " . $sugarCrmSite['sugarInstallDir'] . " is done.\n", $sugarCrmSite['name'],$package); $revisionNumberInstalledInSite[$package] = $packageRevisionInSvn; } else { ciLog ("No updates found (installed: $packageRevisionInstalled, svn: $packageRevisionInSvn).\n", $sugarCrmSite['name'],$package); } } // ciLog what package revisions that were installed saveArrayToFile($siteInstalledVersionsStateFile, $revisionNumberInstalledInSite); // Make sure apache owns the sugar installation $sugarInstallDir = $sugarCrmSite['sugarInstallDir']; $output = `chown -R apache:apache $sugarInstallDir`; } function undeclareFunctions($functions){ foreach($functions as $function) { if (function_exists($function)) { rename_function($function, uniqid()); } } } function ciLog($message, $site, $package){ $fullMessage = "%s %s-%s: " . $message; printf($fullMessage, date('m/d/Y H:i:s'), $site, $package); } function getArrayFromFile($filename){ if (file_exists($filename)) { return unserialize(file_get_contents($filename)); } else { return array(); } } function saveArrayToFile($filename, $arrayToSave){ $fh = fopen($filename, 'w') or die("can't open file"); fwrite($fh, serialize($arrayToSave)); fclose($fh); } ?>
# Command order to get a CentOS 5.6 running with PHP 5.3 and ec2-consistent-snapshot running on AWS # Change hostname hostname YOUR_HOSTNAME vi /etc/sysconfig/network ------------------------------------ HOSTNAME=YOUR_HOSTNAME NETWORKING=yes NETWORKING_IPV6=no ------------------------------------ #Install PHP and modules and APC yum install php53 php53-mbstring php53-mysql php53-gd gd php53-imap php53-ldap php53-pdo php53-cli php53-pear php53-devel httpd-devel pcre-devel php-pear pear upgrade --force Console_Getopt pear upgrade --force pear pear upgrade-all pear version pecl install apc # Attach and mount a AWS EBS volumn (ec2-consistent-snapshot prefers xfs) # Make sure there is xfs support yum install kmod-xfs xfsdump xfsprogs dmapi mkfs.xfs /dev/sdf echo "/dev/sdf /vol xfs defaults,noatime 0 0" >> /etc/fstab mkdir /vol mount /vol # Mysql yum install mysql-server mkdir /vol/mysql chown -R mysql:mysql /vol/mysql vi /etc/my.cnf # Change the my.cnf file to ------------------------------------ [mysqld] datadir=/vol/mysql user=mysql log-warnings=2 log-error=/var/log/mysqld.log default-storage-engine=innodb skip-bdb socket=/var/lib/mysql/mysql.sock [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ------------------------------------ service mysqld start mysqladmin -u root password YOUR_PASSWORD chkconfig mysqld on # ec2-consistent-snapshot perl -MCPAN -e shell cpan>o conf prerequisites_policy follow cpan>o conf commit perl -MCPAN -e "install(q{Bundle::CPAN})" perl -MCPAN -e "install Net::Amazon::EC2" yum -y install perl-DBD-MySQL yum -y install 'perl(File::Slurp)' yum -y install 'perl(DBI)' yum -y install 'perl(Net::SSLeay)' yum -y install 'perl(IO::Socket::SSL)' yum -y install 'perl(LWP::Protocol::https)' wget http://bazaar.launchpad.net/~alestic/ec2-consistent-snapshot/trunk/download/head:/ec2consistentsnapsho-20090928015038-9m9x0fc4yoy54g4j-1/ec2-consistent-snapshot mkdir /home/ec2/bin/ mv ec2-consistent-snapshot /home/ec2/bin/ chmod 700 /home/ec2/bin/ec2-consistent-snapshot # Create / EBS snapshot script cd /root vi snapshot_ebs_root.sh ------------------------------------ #!/bin/sh PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/home/ec2/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/ho me/ec2/bin:/root/bin description="`hostname`-rootdrive-`date +%Y-%m-%d-%H-%M-%S`" ec2-consistent-snapshot --aws-access-key-id=YOUR_ACCESS_KEY --aws-secret-access-key=YOUR_SECRET_ACCESS_KEY \ --description=$description --region=eu-west-1 YOUR_VOLUME_ID ------------------------------------ chmod 700 snapshot_ebs_root.sh # Create /vol EBS snapshot script vi ./snapshot_ebs_vol.sh ------------------------------------ #!/bin/sh PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/home/ec2/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/ho me/ec2/bin:/root/bin description="`hostname`-rootdrive-`date +%Y-%m-%d-%H-%M-%S`" ec2-consistent-snapshot --aws-access-key-id=YOUR_ACCESS_KEY --aws-secret-access-key=YOUR_SECRET_ACCESS_KEY \ --mysql-username=root --mysql-password=YOUR_DB_ROOT_PASSWORD --mysql-host=localhost --description=$description --mysql --region=eu-west-1 \ --freeze-filesystem='/vol' YOUR_VOLUME_ID ------------------------------------ chmod 700 snapshot_ebs_vol.sh #Set the cronschedule for EBS snapshots crontab -e ------------------------------------ 54 6-23 * * * /root/snapshot_ebs_vol.sh > /dev/null 2>&1 59 22 * * * /root/snapshot_ebs_root.sh > /dev/null 2>&1 ------------------------------------ # Change httpd DocumentRoot to /vol/www/default vi /etc/httpd/conf/httpd.conf mkdir /vol/www/default mkdir /vol/www/sites chown -R apache:apache /vol/www chkconfig httpd on service httpd start #Set server timezone cd /etc ln -sf /usr/share/zoneinfo/CET localtime
rm -f /<SUGARCRM_INSTALL_DIR>/cache/upload/*.zip rm -fr /<SUGARCRM_INSTALL_DIR>/cache/upload/upgrades/module/* rm -fr /<SUGARCRM_INSTALL_DIR>/cache/upload/upgrades/temp/* # truncate table upgrade_history in instance database
# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing ...
setenforce 0
yum install httpd yum install php yum install php-mbstring php-mysql php-gd gd php-imap php-ldap yum install html2ps
yum install php-pear php-devel httpd-devel pcre-devel
pear config-set http_proxy http://myproxy.yourdomain.com:8080/
pecl install apc
memory_limit = 512M max_execution_time = 300 error_reporting = E_ALL & ~E_NOTICE post_max_size = 64M upload_max_filesize = 64M
extension=apc.so [apc] apc.cache_by_default=0 # disable by default
#NameVirtualHost *:80
NameVirtualHost *:80
<VirtualHost *:80 > ServerName "HOSTNAME" DocumentRoot /var/www/sites/HOSTNAME DirectoryIndex index.html index.php ErrorLog logs/HOSTNAME-error_log CustomLog logs/HOSTNAME-access_log common <Directory "/var/www/sites/HOSTNAME"> SetOutputFilter DEFLATE AddDefaultCharset UTF-8 AllowOverRide All Options FollowSymlinks # Enable ETag FileETag MTime Size # Set expiration header ExpiresActive on ExpiresDefault "access plus 1 year" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType text/css "access plus 1 month" ExpiresByType text/javascript "access plus 1 month" ExpiresByType text/js "access plus 1 month" # Compress some text file types AddOutputFilterByType DEFLATE text/html text/css text/xml application/x-javascript text/javascript text/js # Deactivate compression for buggy browsers BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html </Directory> </VirtualHost>
wget http://download.oracle.com/otn-pub/java/jdk/6u25-b06/jdk-6u25-linux-x64.bin chmod 755 jdk-6u25-linux-x64.bin ./jdk-6u25-linux-x64.bin
java --version unlink /usr/bin/java ln -s /usr/java/jdk1.6.0_04/bin/java /usr/bin/java java -version
yum install mysql-server
datadir=/<MY_CUSTOM_DATADIR_DIRECTORY_PATH>/mysql # an example datadir=/data/mysql
service mysqld start chkconfig mysqld on
log-warnings=2 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid default-storage-engine=innodb
service mysqld restart
mysqladmin -u root -p password '<MY_ROOT_PASSWORD>'Create a database for the SugarCRM installation.
mysql -uroot -p<MY_ROOT_PASSWORD> create database sugarcrm;
CREATE USER 'sugarcrm_user'@'localhost' IDENTIFIED BY 'mypass'; GRANT ALL ON sugarcrm.* TO 'sugarcrm_user'@'localhost'; CREATE USER 'sugarcrm_user'@'127.0.0.1' IDENTIFIED BY 'mypass'; GRANT ALL ON sugarcrm.* TO 'sugarcrm_user'@'127.0.0.1'; CREATE USER 'sugarcrm_user'@'<APACHE_SERVER_IP_ADDRESS>' IDENTIFIED BY 'mypass'; GRANT ALL ON sugarcrm.* TO 'sugarcrm_user'@'<APACHE_SERVER_IP_ADDRESS>';
GRANT SUPER on *.* to 'sugarcrm_user'@'localhost'; GRANT SUPER on *.* to 'sugarcrm_user'@'127.0.0.1'; GRANT SUPER on *.* to 'sugarcrm_user'@'<APACHE_SERVER_IP_ADDRESS>';
iptables -A INPUT -i eth0 -s <APACHE_SERVER_IP_ADDRESS> -p tcp --destination-port 3306 -j ACCEPT service iptables save
tar -czf mysite.somewhere.com.tar.gz mysite.somewhere.com
mysqldump -h<HOSTNAME> -u<USERNAME> -p<PASSWORD> --triggers --routines <DATABASE> | perl -pe 's/MyISAM/InnoDB/' | perl -pe 's{(/\*!\d+ )\s*definer\s*=\s*\S+}{$1}i' > mysite.somewhere.com.sql gzip mysite.somewhere.com.sql
wget http://my.staging.server/mysite.somewhere.com.tar.gz wget http://my.staging.server/mysite.somewhere.com.sql.gz tar -xf mysite.somewhere.com.tar.gz mv mysite.somewhere.com /var/www/sites/HOSTNAME #(HOSTNAME as defined in the Apache virtualhost conf file) chown -R apache:apache /var/www/sites/HOSTNAME #(HOSTNAME as defined in the Apache virtualhost conf file) #Secure directories chmod -R 644 * find . -type d | xargs chmod 755 chmod 664 config.php chmod 775 ./custom chmod 775 ./data/upload chmod 775 ./data/upload chmod 775 ./cache chmod 775 ./cache/images chmod 775 ./cache/import chmod 775 ./cache/layout chmod 775 ./cache/pdf chmod 775 ./cache/upload chmod 775 ./cache/xml chmod 775 ./modules
gunzip mysite.somewhere.com.sql.gz mysql -h<DATABASEHOSTNAME> -usugarcrm_user -pmypass -D sugarcrm < mysite.somewhere.com.sqledit the /var/www/sites/HOSTNAME/config.php file and make sure the following variables are updated with your own values
'dbconfig' => array ( 'db_host_name' => '', 'db_host_instance' => 'SQLEXPRESS', 'db_user_name' => '', 'db_password' => '', 'db_name' => '', 'db_type' => 'mysql', 'host_name' => '', 'site_url' => 'http://', 'unique_key' => '',unique_key should be unique for each different server.
comment the following line #RedirectMatch /modules/(.*)/(.*).php http://XXXXX/index.php add the following line php_flag apc.cache_by_default OnAfter running the site for a while, tweak your MySQL config file using MySQLTuner
wget --no-check-certificate https://raw.github.com/rackerhacker/MySQLTuner-perl/master/mysqltuner.pl perl mysqltuner.pl
// Using WindsorControllerFactory rather then DependencyResolver // http://bradwilson.typepad.com/blog/2010/07/service-location-pt1-introduction.html (read comments) // http://bradwilson.typepad.com/blog/2010/10/service-location-pt5-idependencyresolver.html (read comments) // http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html (read comments) // http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html // http://kozmic.pl/2010/08/19/must-windsor-track-my-components/ ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(applicationWideWindsorContainer)); // Initialize / install components in container applicationWideWindsorContainer.Install(new WindsorInstaller());As well as the the field
WindsorContainer applicationWideWindsorContainer = new WindsorContainer();This leads to our Global.asax files looking like this
using System.Web.Mvc; using System.Web.Routing; using Castle.Windsor; namespace IocLifestyles { // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Default", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); } WindsorContainer applicationWideWindsorContainer = new WindsorContainer(); protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); // Using WindsorControllerFactory rather then DependencyResolver // http://bradwilson.typepad.com/blog/2010/07/service-location-pt1-introduction.html (read comments) // http://bradwilson.typepad.com/blog/2010/10/service-location-pt5-idependencyresolver.html (read comments) // http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html (read comments) // http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html // http://kozmic.pl/2010/08/19/must-windsor-track-my-components/ ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(applicationWideWindsorContainer)); // Initialize / install components in container applicationWideWindsorContainer.Install(new WindsorInstaller()); } } }
using System; using System.Web.Mvc; using System.Web.Routing; using Castle.Windsor; namespace IocLifestyles { public class WindsorControllerFactory : DefaultControllerFactory { private readonly IWindsorContainer windsorContainer; public WindsorControllerFactory(IWindsorContainer windsorContainer) { this.windsorContainer = windsorContainer; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return windsorContainer.Resolve(controllerType) as IController; } public override void ReleaseController(IController controller) { var disposableController = controller as IDisposable; if (disposableController != null) { disposableController.Dispose(); } windsorContainer.Release(controller); } } }Now we need to register the classes which we are going to use through out our application with the IoC container and we do this by implementing the IWindsorInstaller interface.
using System.Web.Mvc; using Castle.Facilities.FactorySupport; using Castle.MicroKernel.Registration; using Castle.MicroKernel.SubSystems.Configuration; using Castle.Windsor; using System.Web; namespace IocLifestyles { public class WindsorInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { // Register all controllers from this assembly container.Register( AllTypes.FromThisAssembly() .BasedOn<Controller>() .Configure(c => c.LifeStyle.PerWebRequest) ); // Register HttpContext(Base) and HttpRequest(Base) so it automagically can be injected using IoC container.AddFacility<FactorySupportFacility>(); container.Register(Component.For<HttpRequestBase>().LifeStyle.PerWebRequest .UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request))); container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest .UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); // Respository and Service registrations container.Register(Component.For<ISomeRepository>().ImplementedBy<SomeRepository>()); container.Register(Component.For<ISessionValidator>().ImplementedBy<SessionValidator>().LifeStyle.PerWebRequest); } } }
namespace IocLifestyles { public interface ISomeRepository { SessionToken GetSessionToken(); } public class SomeRepository : ISomeRepository { private readonly ISessionValidator sessionValidator; public SomeRepository(ISessionValidator sessionValidator) { this.sessionValidator = sessionValidator; } public SessionToken GetSessionToken() { return sessionValidator.ValidateSession(); } } }
using System.Net; using System.Web; namespace IocLifestyles { public interface ISessionValidator { SessionToken ValidateSession(); } public class SessionValidator : ISessionValidator { private readonly HttpContextBase httpContextBase; public SessionValidator(HttpContextBase httpContextBase) { this.httpContextBase = httpContextBase; } public SessionToken ValidateSession() { // Do some validation here var sessionToken = new SessionToken { IpAddress = IPAddress.Parse(httpContextBase.Request.UserHostAddress), IsValid = true }; return sessionToken; } } }The final 2 pieces needed to actually see something in the browser is the DefaultController
using System.Web.Mvc; namespace IocLifestyles.Controllers { public class DefaultController : Controller { private readonly ISomeRepository someRepository; // Constructor Injection public DefaultController(ISomeRepository someRepository) { this.someRepository = someRepository; } public ActionResult Index() { ViewData.Model = someRepository.GetSessionToken(); return View(); } } }
@model IocLifestyles.SessionToken @{ ViewBag.Title = "Index"; } <h2> SessionToken IpAddress: @Model.IpAddress.ToString()</h2>
Server Error in '/' Application. Object reference not set to an instance of an object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.NullReferenceException: Object reference not set to an instance of an object. Source Error: Line 20: { Line 21: // Do some validation here Line 22: var sessionToken = new SessionToken Line 23: { Line 24: IpAddress = IPAddress.Parse(httpContextBase.Request.UserHostAddress), Source File: D:\Users\kst\Visual Studio 2010\projects\IocLifestyles\IocLifestyles\SessionValidator.cs Line: 22 Stack Trace: [NullReferenceException: Object reference not set to an instance of an object.] Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0 Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress() +65 System.Web.HttpRequestWrapper.get_UserHostAddress() +22 IocLifestyles.SessionValidator.ValidateSession() in D:\Users\kst\Visual Studio 2010\projects\IocLifestyles\IocLifestyles\SessionValidator.cs:22 IocLifestyles.SomeRepository.GetSessionToken() in D:\Users\kst\Visual Studio 2010\projects\IocLifestyles\IocLifestyles\SomeRepository.cs:19 IocLifestyles.Controllers.DefaultController.Index() in D:\Users\kst\Visual Studio 2010\projects\IocLifestyles\IocLifestyles\Controllers\DefaultController.cs:17 lambda_method(Closure , ControllerBase , Object[] ) +96 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27 System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343 System.Web.Mvc.Controller.ExecuteCore() +116 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10 System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37 System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21 System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50 System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862285 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184 Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.208
using System.Web.Mvc; using Castle.Facilities.FactorySupport; using Castle.MicroKernel.Registration; using Castle.MicroKernel.SubSystems.Configuration; using Castle.Windsor; using System.Web; namespace IocLifestyles { public class WindsorInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { // Register all controllers from this assembly container.Register( AllTypes.FromThisAssembly() .BasedOn<Controller>() .Configure(c => c.LifeStyle.PerWebRequest) ); // Register HttpContext(Base) and HttpRequest(Base) so it automagically can be injected using IoC container.AddFacility<FactorySupportFacility>(); container.Register(Component.For<HttpRequestBase>().LifeStyle.PerWebRequest .UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request))); container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest .UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); // Respository and Service registrations container.Register(Component.For<ISomeRepository>().ImplementedBy<SomeRepository>()); container.Register(Component.For<ISessionValidator>().ImplementedBy<SessionValidator>().LifeStyle.PerWebRequest); } } }
using System.Web.Mvc; using Castle.Facilities.FactorySupport; using Castle.MicroKernel.Registration; using Castle.MicroKernel.SubSystems.Configuration; using Castle.Windsor; using System.Web; namespace IocLifestyles { public class WindsorInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { // Register all controllers from this assembly container.Register( AllTypes.FromThisAssembly() .BasedOn<Controller>() .Configure(c => c.LifeStyle.PerWebRequest) ); // Register HttpContext(Base) and HttpRequest(Base) so it automagically can be injected using IoC container.AddFacility<FactorySupportFacility>(); container.Register(Component.For<HttpRequestBase>().LifeStyle.PerWebRequest .UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request))); container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest .UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); // Respository and Service registrations container.Register(Component.For<ISomeRepository>().ImplementedBy<SomeRepository>().LifeStyle.PerWebRequest); container.Register(Component.For<ISessionValidator>().ImplementedBy<SessionValidator>().LifeStyle.PerWebRequest); } } }
throw null;where a more verbosely inclined programmer would have written
throw new NullReferenceException();So I set out to find out if these 2 uses indeed are equivalent.
using System; namespace NullRefernceException { public class Class1 { public void DoSomething() { throw null; } } }
.method public hidebysig instance void DoSomething() cil managed { // Code size 2 (0x2) .maxstack 8 IL_0000: ldnull IL_0001: throw } // end of method Class1::DoSomething
System.NullReferenceException: Object reference not set to an instance of an object. at NullRefernceException.Class1.DoSomething() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1.cs:line 8 at NullRefernceException.Class1Tests.DoSomething_TestDriveNullReferenceException_ExceptionThrown() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1Tests.cs:line 15
using System; namespace NullRefernceException { public class Class1 { public void DoSomething() { throw new NullReferenceException(); } } }
.method public hidebysig instance void DoSomething() cil managed { // Code size 6 (0x6) .maxstack 8 IL_0000: newobj instance void [mscorlib]System.NullReferenceException::.ctor() IL_0005: throw } // end of method Class1::DoSomething
System.NullReferenceException: Object reference not set to an instance of an object. at NullRefernceException.Class1.DoSomething() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1.cs:line 8 at NullRefernceException.Class1Tests.DoSomething_TestDriveNullReferenceException_ExceptionThrown() in D:\Users\kst\Visual Studio 2010\projects\NullRefernceException\NullRefernceException\Class1Tests.cs:line 15
using System; using NUnit.Framework; namespace NullRefernceException { [TestFixture] public class Class1Tests { [Test] public void DoSomething_TestDriveNullReferenceException_ExceptionThrown() { var class1 = new Class1(); try { class1.DoSomething(); } catch (Exception exception) { Console.WriteLine(exception); } } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.Web.Administration; namespace UpdateIisApplicationPaths { public partial class Form1 : Form { private readonly ServerManager serverManager = new ServerManager(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { foreach (var site in serverManager.Sites) { websitesListBox.Items.Add(site.Name); } } private void commitChangesButton_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; foreach (var sitename in websitesListBox.SelectedItems) { var physicalPath = serverManager.Sites[(string) sitename].Applications[0].VirtualDirectories[0].PhysicalPath; physicalPath = physicalPath.Replace(oldPhysicalSitePathTextBox.Text, newPhysicalSitePathTextBox.Text); serverManager.Sites[(string) sitename].Applications[0].VirtualDirectories[0].PhysicalPath = physicalPath; } serverManager.CommitChanges(); Cursor.Current = Cursors.Default; } private void websitesListBox_SelectedIndexChanged(object sender, EventArgs e) { if (websitesListBox.SelectedItems.Count > 0) { oldPhysicalSitePathTextBox.Text = serverManager.Sites[(string) websitesListBox.SelectedItems[0]].Applications[0].VirtualDirectories[0].PhysicalPath; } } } }
var factory = new ChannelFactory<IService1Wrapper>("Service1WrapperREST");var proxy = factory.CreateChannel(); try { var serviceResult = proxy.GetProductById("1"); // Do something with result } catch (Exception exceptionThrownByRestWcfCall) { var serviceResult = WcfRestExceptionHelper<SampleItem[], SampleError>.HandleRestServiceError(exceptionThrownByRestWcfCall); // Do something with result, let higher levels in the callstack handle possible real exceptions } finally { ((IDisposable)proxy).Dispose(); }
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using System.ServiceModel; using System.Text; using System.Xml.Serialization; namespace WcfRestClient.WcfErrors { public static class WcfRestExceptionHelper<TServiceResult, TServiceFault> where TServiceFault : class { private static IDictionary<Type, XmlSerializer> cachedSerializers = new Dictionary<Type, XmlSerializer>(); public static TServiceResult HandleRestServiceError(Exception exception) { if (exception == null) throw new ArgumentNullException("exception"); // REST uses the HTTP procol status codes to communicate errors that happens on the service side. // This means if we have a teller service and you need to supply username and password to login // and you do not supply the password, a possible scenario is that you get a 400 - Bad request. // However it is still possible that the expected type is returned so it would have been possible // to process the response - instead it will manifest as a ProtocolException on the client side. var protocolException = exception as ProtocolException; if (protocolException != null) { var webException = protocolException.InnerException as WebException; if (webException != null) { var responseStream = webException.Response.GetResponseStream(); if (responseStream != null) { try { // Debugging code to be able to see the reponse in clear text //SeeResponseAsClearText(responseStream); // Try to deserialize the returned XML to the expected result type (TServiceResult) return (TServiceResult) GetSerializer(typeof(TServiceResult)).Deserialize(responseStream); } catch (InvalidOperationException serializationException) { // This happens if we try to deserialize the responseStream to type TServiceResult // when an error occured on the service side. An service side error serialized object // is not deserializable into a TServiceResult // Reset responseStream to beginning and deserialize to a TServiceError instead responseStream.Seek(0, SeekOrigin.Begin); var serviceFault = (TServiceFault)GetSerializer(typeof(TServiceFault)).Deserialize(responseStream); throw new WcfRestServiceException<TServiceFault>() { ServiceFault = serviceFault }; } } } } // Don't know how to handle this exception throw exception; } /// <summary> /// Based on the knowledge of how the XmlSerializer work, I found it safest to explicitly implement my own caching mechanism. /// /// From MSDN: /// To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and /// deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when /// using the following constructors: /// /// XmlSerializer.XmlSerializer(Type) /// XmlSerializer.XmlSerializer(Type, String) /// /// If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, /// which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned /// two constructors. Otherwise, you must cache the assemblies. /// /// </summary> /// <param name="classSpecificSerializer"></param> /// <returns></returns> private static XmlSerializer GetSerializer(Type classSpecificSerializer) { if (!cachedSerializers.ContainsKey(classSpecificSerializer)) { cachedSerializers.Add(classSpecificSerializer, new XmlSerializer(classSpecificSerializer)); } return cachedSerializers[classSpecificSerializer]; } /// <summary> /// Debugging helper method in case there are problems with the deserialization /// </summary> /// <param name="responseStream"></param> private static void SeeResponseAsClearText(Stream responseStream) { var responseStreamLength = responseStream.Length; var buffer = new byte[responseStreamLength]; var x = responseStream.Read(buffer, 0, Convert.ToInt32(responseStreamLength)); var enc = new UTF8Encoding(); var response = enc.GetString(buffer); Debug.WriteLine(response); responseStream.Seek(0, SeekOrigin.Begin); } } }The generic exception that we can throw
using System; namespace WcfRestClient.WcfErrors { public class WcfRestServiceException<TServiceError> : Exception where TServiceError : class { public WcfRestServiceException() : base("An service error occured. Please inspect the ServiceError property for details.") { } public TServiceError ServiceFault { get; set; } } }