How do I create and deploy a Windows service in EWL? - c#

I know EWL has support for services, but I'm not sure what is different about them or what steps I have to take to create one.
Also, is it possible to manually deploy an EWL service in the same manner as a conventional service, or do I have to use the deployment utility?

EWL services give you a simple programming model, with only three places you can put your logic: the Init, CleanUp, and Tick methods. Besides deciding how to divide your logic among these methods, no thinking is required. There is also no flexibility beyond these three methods, so if your problem doesn't neatly fit into this model, don't use an EWL service.
To create an EWL service inside an existing EWL solution:
Add a Windows Service project to your solution. Name it "Windows Service" or anything else. Set it to use the EWL NuGet package, just like the other projects in your solution.
In Library/Configuration/General.xml, add a section like this beneath <WebApplications>:
<WindowsServices>
<Service>
<Name>YOUR-SERVICE-PROJECT-NAME</Name>
<NamespaceAndAssemblyName>YOUR-SERVICE-PROJECT-NAMESPACE</NamespaceAndAssemblyName>
</Service>
</WindowsServices>
Update dependent logic.
Show hidden files in your service project, and add Generated Code/ISU.cs.
Add a Program.cs file to the project, containing this class:
internal partial class Program {
static partial void initGlobalLogic( ref SystemLogic globalLogic ) {
globalLogic = new GlobalLogic();
}
}
Add a CAMEL-CASED-SERVICE-PROJECT-NAME.cs file to the project, containing a class similar to:
internal partial class CAMEL-CASED-SERVICE-PROJECT-NAME {
string WindowsServiceBase.Description { get { return "..."; } }
void WindowsServiceBase.Init() {}
void WindowsServiceBase.CleanUp() {}
void WindowsServiceBase.Tick() {}
}
Remove any boilerplate files in your project that seem unnecessary.
I believe you can install EWL services manually. Just do a build and do whatever you need to with the files in the bin directory.

Related

c# two web references, one for live on for test

I have an issue. My boss has setup a test SOAP web service that he wants use to consume in our API.
Originally we only had one, so it was straight forward enough.
Now we have two and they are on different endpoints, so I created 2 Web References that look like this:
http://ssd-001/tradeportal/webservices.asmx?wsdl
http://ssd-001/testtradeportal/webservices.asmx?wsdl
We are using autofac and I was able to register the service like this:
builder.RegisterType<webServices>().As<webServices>().InstancePerDependency();
I was going to create a factory class to switch between the two, but the issue I have is that even though they are both a webServices class, they are on different name spaces and do not have an interface or anything.
The only thing I could find was that they both inherit from System.Web.Services.Protocols.SoapHttpClientProtocol, but registering that would lose any of the public methods which I need.
Does anyone know or can think of any suggestions that might help me get around this issue?
Basically I want one class to switch between the two depending on if we are live or not, we currently have a flag in a config file for that.
As #Zohar mentioned, the web services are the same; it's just the URL that is different. So I added an entry to my web.config file and then created a factory class like this:
public static class TradePortalFactory
{
public static webServices Create(CormarConfig config) => new webServices { Url = config.TradePortalUrl };
}
Then I could change my autofac register to this:
builder.Register(m => TradePortalFactory.Create(m.Resolve<CormarConfig>())).As<webServices>().InstancePerDependency();

Automatically alter C# WSDL generated code

In Visual Studio, is there a way to automatically alter source code and add a specific attribute to methods either prior to building or as part of the build process? Similar to code generation except I'm not generating the code, it already exists. Can something like T4 handle this? I don't want to manually add these attributes, I want it to be an automatic, repeatable process.
For example:
public class Test
{
public void MethodOne()
{
}
public void MethodTwo()
{
}
}
Automatically becomes:
public class Test
{
[CustomAttribute]
public void MethodOne()
{
}
[CustomAttribute]
public void MethodTwo()
{
}
}
Background:
I'm using a 3rd party product called Xamarin to build Android + iOS apps using .NET. I'm consuming a SOAP web service using WSDL.exe to automatically generate a proxy. I've added an a custom web service SOAP extension on the client side and the only reliable way I've found of wiring up that custom extension is adding a custom attribute to each web service method generated in the client web service proxy. I have to repeat this process each time I update the web service proxy since it generates fresh code each time.
Couple notes about Xamarin limitations. I don't have access to a web.config or app.config file, which is the normal way of wiring up custom web service SOAP extensions. Xamarin doesn't support web.config or app.config files. I can't use newer technologies like WCF because Xamarin doesn't fully support them (support is still in beta and I've encountered some bugs that prevented me from using them)
I accomplished this using your test class. I'm on Visual Studio 2010, but assume it'll work in 2012.
Open up a Find/Replace window. Switch to the Quick Replace tab. Make sure Use Regular Expressions is checked under Find Options.
Enter this for Find What:
public void Method
Enter this for Replace With:
[CustomAttribute]\n\tpublic void Method

Configuration settings placement in 3-layered application

In a standard 3-layered application (Winforms Ui, BLL, DAL) i need to have settings specific for each layer.
Should i use the Winforms application settings to include all of them or i should have each dll (BLL,DAL) come with their settings?
I need a simple solution and not in a database or custom xmls, also i need to provide multiple UIs for the same architecture.
Update: Currently i am leaning towards separate .config files for each layer, i just dont know if this is the best practice that will allow for most of future changes (changes in layers and/or multiple UI apps).
Outcome: I think i am gonna have a static singleton class in every project that i need settings. I am gonna populate them by the upper layer every time with the most suitable way.
Custom xml file is flexible approach but need a bit effort.
Use a separate library project only to serve for settings, its easier way as you may use default settings class to save/load settings but not very flexible for nested settings.
Put all settings with DAL since it live at root and all other projects (UI, BAL) reference it)
Every time I tried to use the built-in app.config file, I ended up implementing my own config solution due to shortcomings of the built-in solution. Implementing a custom xml-based solution is not complex. It is actually very easy.
Just put this base class into your solution:
[Serializable]
public abstract class ConfigBase<DerivedT> where DerivedT : ConfigBase<DerivedT>
{
protected string FilePath;
public string FileVersion;
public ConfigBase() { }
public void Save()
{
XmlSerializer xs = new XmlSerializer(GetType());
using (StreamWriter writer = File.CreateText(FilePath))
{
xs.Serialize(writer, this);
}
}
public static DerivedT Load(string filename)
{
XmlSerializer xs = new XmlSerializer(typeof(DerivedT));
using (StreamReader reader = File.OpenText(filename))
{
DerivedT config = (DerivedT)xs.Deserialize(reader);
config.FilePath = filename;
return config;
}
}
}
Then you can make your configuration file like this:
public class Config : ConfigBase<Config>
{
// put your variables here like below
public string DatabaseConnectionString;
public int numberOfConnections;
}
Use it like this:
// Load it like this
Config config = Config.Load(ConfigFileName);
// Save it like this
config.Save();
Feel free to use properties, arrays and other complex structures within the config file. It will all serialize automatically. Use XmlIgnore attribute if you do not want certain fields/properties serialized. With this solution you can have many different configuration files, but have a single mechanism to load and save them.
I often include a public static Config GenerateDefault(string ConfigFileName) factory method inside the Config file, which will produce a sample config with default values.
Don't forget to check if the file file exists and load it within a try/catch block.
An even better solution would be to use DataContracts, which allows you to serialize private members and provides good mechanisms for supporting different versions of DataContracts, but it is a bit more complex.
If all your layers are running in the same AppDomain (rather than, say, hosting the BLL/DAL in a WCF service), then the KISS solution is to include all the configuration information in the client's app.config file.
You can use a naming convention to distinguish settings belonging to each layer.
UPDATE
From comment:
Currently yes, but I would like to be free to change later even the DAL presentation (via WCF for example).
That's simple: when you move a logical tier into a different physical tier such as WCF, you move its configuration into the configuration file for the host (e.g. web.config if the host is IIS).

Access web.config from separate Class Library?

I'm looking for a good way to achieve the following:
I have a web application (MVC 3), with a separate Class Library that contains the back-end logic of a CMS that I'm making. This CMS uses NHibernate to connect to a database. I want the user to be able to configure the connectionstring (and eventually even the flavour of the database) in their web.config file.
What I'm looking for is a good way to get the connection string from the web.config file, even though the DLL is completely separate. Is this possible? Will I have to pass my connection string to my class library somehow? Or will I be able to access it when the application runs?
If I have to create some code in my web application to pass the connection string to my Class Library, how can I make this code as portable as possible, so I won't have to write it again for my next webapp?
Thanks a lot for any ideas you have.
You can pass in the connection string to the classes in the class library from the web site.
This is a better choice than trying to get the information directly from the configuration file, as otherwise you will have a dependency on the configuration file existing with the exact right key (making testing the class somewhat harder).
See this blog post for arguments against accessing configuration directly (which is very commonly done, but is not best practice).
You can access System.Configuration.ConfigurationManager from your class library. That'll give you access to the AppSettings and ConnectionStrings.
I have exactly the same setup with a FOSS project I'm involved with. It contains everything (even the Controllers and Global.asax.cs) in the 'Core' class library.
There's plenty of valid solutions, the one I opted for was to create a Settings class which is essentially a set of static properties, inside which you have:
public static string ConnectionString
{
get { return ConfigurationManager.ConnectionStrings["MYAPP"].ConnectionString; }
}
Note: make sure your class library has System.Configuration added as a reference.
Inside your Application (the class derived from HttpApplication) you pass the settings across, although there is nothing to stop you tighly coupling the NH setup with the settings class:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
SetupNHibernate();
}
public virtual void SetupNHibernate()
{
NHibernateRepository.Current.Configure(RoadkillSettings.DatabaseType, Settings.ConnectionString, false, Settings.CachedEnabled);
}
If this is any use to you, the source is here.
You can use the ConfigurationManager class to access items in your web.config or app.config file. However, in your class library, be sure to take in the key name of any appSettings and/or connectionString settings from the consumer (preferably in the constructor). This avoids the problem of you choosing a key name that the consumer is already using elsewhere.
Since you are using the class library to the MVC web application, it is accessible to the class library also. No additional settings are needed. Even though the class library when built giving a separate dll, it is referenced in the current project. So the connection string will be available to the class library also.
I'd go with something like Autofac to give you some IoC implementation which can store a settings interface for your connection strings. This would allow you to setup the value from the web.config on application start, or to set it within tests to a different value without your Class Library ever having to be coupled to a web.config.
You can add new Existing item from another project to your class library. Then change Build Action to Embedded Resource and Copy to Output Directory to Copy if newer on the Web.config file.
Web.config in another project
<configuration>
<appSettings>
<add key="MyConfigValue" value="Test" />
</appSettings>
</configuration>
Class library test file
var doc = XDocument.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web.config"));
var myConfigValue = doc.Element("configuration")
.Element("appSettings")
.Elements("add")
.FirstOrDefault(e => e.Attribute("key").Value == "MyConfigValue").Attribute("value").Value;

How to configure AutoMapper if not ASP.net Application?

I'm using AutoMapper in a number of projects within my solution.
These projects may be deployed independantly, across multiple servers.
In the documentation for AutoMapper it says:
If you're using the static Mapper
method, configuration only needs to
happen once per AppDomain. That means
the best place to put the
configuration code is in application
startup, such as the Global.asax file
for ASP.NET applications.
Whilst some of the projects will be ASP.net - most of these are class libraries / windows services.
Where should I be configuring my mappings in this case?
The idea that it should only be required once per AppDomain stays the same, as far as I can tell. I always perform my mappings upon the initialization of the program itself. While I am not using AutoMapper I am using an IoC library (Windsor) which requires a mapping of sorts and this is done from my program.cs file. So when the application loads it performs the mapping and because the resolver is static and in a shared library it is available globally.
I don't know if this answers your question or not, but essentially every app has an entry point and if you need your mappings immediately after entry then the entry is the best place to put them.
I've elected to store my mappings in separate classes for each project so that they are reusable.
protected void Application_Start()
{
RegisterMaps();
}
private void RegisterMaps()
{
WebAutoMapperSettings.Register();
BusinessLogicAutoMapperSettings.Register();
}
This way I can easily call BusinessLogicAutoMapperSettings.Register() if I were to reuse only my BusinessLogic dll in another application or webservice

Categories