I have generated ServiceContext for my CRM organization. I'm able to connect to CRM properly. Since I have all my context configuration in app.config file, I wonder is it possible to get IOrganizationService from already instantiated OrganizationServiceContext?
When I need to access the service reference from multiple places, I usually do it in two steps. First of all I try to see if it's possible to pass it down to the called methods (I'm assuming that you have something like the following).
using (IOrganizationService service
= (IOrganizationService) new OrganizationServiceProxy(...))
{
DoSomething();
DoSomething(service);
}
private void DoSomething(IOrganizationService service) { ... }
When it fails (due to technical setup or just plain dumbness), I set up a private property and in the constructor (or at least the first calling method) assign it a value for future access like this.
class MyClass
{
private IOrganization _service;
private IOrganization _Service
{
get
{
if(_service == null)
_service = (IOrganizationService) new OrganizationServiceProxy(...);
return _service;
}
}
...
}
And if you have a lot of code that operates on the server, you might want to move all that stuff to a separate class and have the calls made to it (with the property setup discussed above).
I'm not fully sure if I got your question correctly so be nice if I'm missing your point.
Related
I process messages from a queue. I use data from the incoming message to determine which class to use to process the message; for example origin and type. I would use the combination of origin and type to look up a FQCN and use reflection to instantiate an object to process the message. At the moment these processing objects are all simple POJOs that implement a common interface. Hence I am using a strategy pattern.
The problem I am having is that all my external resources (mostly databases accessed via JPA) are injected (#Inject) and when I create the processing object as described above all these injected objects are null. The only way I know to populate these injected resources is to make each implementation of the interface a managed bean by adding #stateless. This alone does not solve the problem because the injected members are only populated if the class implementing the interface is itself injected (i.e. container managed) as opposed to being created by me.
Here is a made up example (sensitive details changed)
public interface MessageProcessor
{
public void processMessage(String xml);
}
#Stateless
public VisaCreateClient implements MessageProcessor
{
#Inject private DAL db;
…
}
public MasterCardCreateClient implements MessageProcessor…
In the database there is an entry "visa.createclient" = "fqcn.VisaCreateClient", so if the message origin is "Visa" and the type is "Create Client" I can look up the appropriate processing class. If I use reflection to create VisaCreateClient the db variable is always null. Even if I add the #Stateless and use reflection the db variable remains null. It's only when I inject VisaCreateClient will the db variable get populated. Like so:
#Stateless
public QueueReader
{
#Inject VisaCreateClient visaCreateClient;
#Inject MasterCardCreateClient masterCardCreateClient;
#Inject … many more times
private Map<String, MessageProcessor> processors...
private void init()
{
processors.put("visa.createclient", visaCreateClient);
processors.put("mastercard.createclient", masterCardCreateClient);
… many more times
}
}
Now I have dozens of message processors and if I have to inject each implementation then register it in the map I'll end up with dozens of injections. Also, should I add more processors I have to modify the QueueReader class to add the new injections and restart the server; with my old code I merely had to add an entry into the database and deploy the new processor on the class path - didn't even have to restart the server!
I have thought of two ways to resolve this:
Add an init(DAL db, OtherResource or, ...) method to the interface that gets called right after the message processor is created with reflection and pass the required resource. The resource itself was injected into the QueueReader.
Add an argument to the processMessage(String xml, Context context) where Context is just a map of resources that were injected into the QueueReader.
But does this approach mean that I will be using the same instance of the DAL object for every message processor? I believe it would and as long as there is no state involved I believe it is OK - any and all transactions will be started outside of the DAL class.
So my question is will my approach work? What are the risks of doing it that way? Is there a better way to use a strategy pattern to dynamically select an implementation where the implementation needs access to container managed resources?
Thanks for your time.
In a similar problem statement I used an extension to the processor interface to decide which type of data object it can handle. Then you can inject all variants of the handler via instance and simply use a loop:
public interface MessageProcessor
{
public boolean canHandle(String xml);
public void processMessage(String xml);
}
And in your queueReader:
#Inject
private Instance<MessageProcessor> allProcessors;
public void handleMessage(String xml) {
MessageProcessor processor = StreamSupport.stream(allProcessors.spliterator(), false)
.filter(proc -> proc.canHandle(xml))
.findFirst()
.orElseThrow(...);
processor.processMessage(xml);
}
This does not work on a running server, but to add a new processor simply implement and deploy.
I am trying to create a custom manager which is passed in the controller when it is being called and I am having troubles understanding the current implementation of new MVC5 project in c#.
Here is the default implementation:
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
above all of that are declarations for them:
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
Now from my understanding the SignInManager and UserManager get created when application gets created for the first time in Startup.Auth.cs which looks like this:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
So now whenever I call UserManager I will get that first instance that was created when project ran for the first time.
I have 2 questions. Question 1 is is anything I said above wrong and Do I have a wrong understanding of how MVC5 works?
Question2: How is UserManager and SignInManager generated and passed in the controller? Where is the code that creates that first instance of the manager and passes it in the controller? I am assuming it is app.CreatePerOwnContext that does it. If so, can I then just create my own Manager and then register it with Owin in the same fashion and reuse throughout the project? Will my code get the latest data from the database if I do this and not cache it?
The code you're showing is coming from the IMO very ugly MVC5 template, which works out of the box but does some ugly things.
This constructor:
public AccountController(ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
makes you think OWIN automagically injects the managers for you. But in fact this is not the case. That is why the template comes with the ugly properties you supplied in the questions. When you do not change anything to the template, the default constructor is called (also present in the template). To try it, just delete, or comment, the default constructor and you'll see the AccountController can't be created anymore.
So what is actually happening there is that both managers are located using the Service Locator anti pattern in the getters of the supplied properties.
So now whenever I call UserManager I will get that first instance that was created when project ran for the first time?
No this is not the case. What this line:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
does, is creating a delegate to the Create method of both managers. The managers are cached within an Owin Request. The next request the delegates are called again and you get a fresh ApplicationUserManager etc.
To be a little bit more verbose this line could be rewritten as:
Func<ApplicationUserManager> userManagerFactory = () => ApplicationUserMangager.Create();
app.CreatePerOwinContext<ApplicationUserManager>(userManagerFactory);
So if you would a breakpoint here:
public ApplicationUserManager UserManager
{
get
{
// place breakpoint here
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
// ....
You would see that while stepping through the code, you will hit the line where you created the UserManagerFactory which in his turn will call the Create() method of the ApplicationUserManager.
How is UserManager and SignInManager generated and passed in the controller
It isn't! You would need to use dependency injection for that.
If so, can I then just create my own Manager and then register it with Owin in the same fashion and reuse throughout the project
Yes you can. You can completely refactor the ApplicationUserManager you also got 'for free' in the template. As long as you supply a factory method to the 'CreatePerOwinContext' extension method.
Will my code get the latest data from the database if I do this and not cache it?
The instances are cached on per request base. So each request you will get a new one, with a new DbContext etc.
I'm unsure how familiar you are with dependency injection but MVC5 is a pretty easy framework to start with it, IMO.
I once wrote a blogpost how to configure my DI container of choice (Simple Injector) to use with the MVC5 template.
I also wrote several answers here on SO regarding this template: specifically this one, should interest you. This one is interesting also!
I am trying to write a method to create a database and run migrations on it, given the connection string.
I need the multiple connections because I record an audit log in a separate database.
I get the connection strings out of app.config using code like
ConfigurationManager.ConnectionStrings["Master"].ConnectionString;
The code works with the first connection string defined in my app.config but not others, which leads me to think that somehow it is getting the connection string from app.config in some manner I don't know.
My code to create the database if it does not exist is
private static Context MyCreateContext(string ConnectionString)
{
// put the connection string where the factory method can get it
AppDomain.CurrentDomain.SetData("ConnectionString", ConnectionString );
var factory = new ContextFactory();
// I know I need this line - but I cant see how what follows actually uses it
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context,DataLayer.Migrations.Configuration>());
var context = factory.Create();
context.Database.CreateIfNotExists();
return context
}
The code in the Migrations.Configuration is
Public sealed class Configuration : DbMigrationsConfiguration<DataLayer.Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}
The context factory code is
public class ContextFactory : IDbContextFactory<Context>
{
public Context Create()
{
var s = (string)AppDomain.CurrentDomain.GetData("ConnectionString");
return new Context(s);
}
}
Thus I am setting the connection string before creating the context.
Where can I be going wrong, given that the connection strings are all the same except the database name, and the migration code runs with one connection string, but doesnt run with others?
I wonder if my problem is to do with understanding how How does Database.SetInitializer actually works. I am guessing something about reflection or generics. How do i make the call to SetInitializer tie tie to my actual context?
I have tried the following code but the migrations do not run
private static Context MyCreateContext(string ConnectionString)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, DataLayer.Migrations.Configuration>());
var context = new Context(ConnectionString);
context.Database.CreateIfNotExists();
}
This question appears to be related
UPDATE:
I can get the migrations working if I refer to the connection string using
public MyContext() : base("MyContextConnection") - which points to in the config
I was also able to get migrations working on using different instances of the context, if I created a ContextFactory class and passed the connection to it by referencing a global. ( See my answer to the related question link )
Now I am wondering why it has to be so hard.
I'm not sure exactly as to what the problems are you facing, but let me try
The easiest way to provide connection - and be sure it works that way...
1) Use your 'DbContext' class name - and define a connection in the app.config (or web.config). That's easiest, you should have a connection there that matches your context class name,
2) If you put it into the DbContext via constructor - then be consistent and use that one. I'd also suggest to 'read' from config connections - and again name it 'the same' as your context class (use the connection 'name', not the actual string),
3) if none is present - EF/CF makes the 'default' one - based on your provider - and your context's class name - which usually isn't what you want,
You shouldn't customize with initializers for that reason -
initializers should be agnostic and serve other purpose - setup
connection in the .config - or directly on your DbContext
Also check this Entity Framework Code First - How do I tell my app to NOW use the production database once development is complete instead of creating a local db?
Always check 'where your data' goes - before doing anything.
For how the initializer actually works - check this other post of mine, I made a thorough example
How to create initializer to create and migrate mysql database?
Notes: (from the comments)
Connection shouldn't be very dynamic - config is the right place for it to be, unless you have a good reason.
Constructor should work fine too.
CreateDbIfNotExists doesn't work well together with the 'migration' initializer. You can just use the MigrateDatabaseToLatestVersion initializer. Don't 'mix' it
Or - put something like public MyContext() : base("MyContextConnection") - which points to <connectionStrings> in the config
To point to connection - just use its 'name' and put that into constructor.
Or use somehting like ConfigurationManager.ConnectionStrings["CommentsContext"].ConnectionString
Regarding entertaining 'multiple databases' with migrations (local and remote from one app) - not exactly related - but this link - Migration not working as I wish... Asp.net EntityFramework
Update:
(further discussion here - Is adding a class that inherits from something a violation of the solid principles if it changes the behavior of code?)
It is getting interesting here. I did manage to reproduce the problems you're facing actually. Here is a short breakdown on what I think it's happening:
First, this worked 'happily':
Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<MyContext, MyProject.Migrations.Configuration>());
for (var flip = false; true; flip = !flip)
{
using (var db = new MyContext(flip ? "Name=MyContext" : "Name=OtherContext"))
{
// insert some records...
db.SaveChanges();
}
}
(I used custom initializer from my other post, which controls migration/creation 'manually')
That worked fine w/o an Initializer. Once I switched that on, I ran into some curious problems.
I deleted Db-s (two, for each connection). I expected to either not work, or create one db, then another in the next pass (like it did, w/o migrations, just 'Create' initializer).
What happened, to my surprise - is it actually created both databases on the first
pass ??
Then, being a curious person:), I put breakpoints on the MyContext ctor, and debugged through the migrator/initializer. Again empty/no db-s etc.
It created first instance on my call within the flip. Then on the first access to 'model', it invoked the initializer. Migrator took over (having had no db-s). During the migrator.Update(); it actually constructs the MyContext (I'm guessing via generic param in Configuration) - and calls the 'default' empty ctor. That had the 'other connection/name' by default - and creates the other Db all as well.
So, I think this explains what you're experiencing. And why you had to create the 'Factory' to support the Context creation. That seems to be the only way. And setting some 'AppDomain' wide 'connection string' (which you did well actually) which isn't 'overriden' by default ctor call.
Solution that I see is - you just need to run everything through factory - and 'flip' connections in there (no need for static connection, as long as your factory is a singleton.
You can supply a configuration in the MigrateDatabaseToLatestVersion constructor.
If you set the initializer in the DbContext you can also pass a 'true' to use the current connection string.
I have read Evans, Nilsson and McCarthy, amongst others, and understand the concepts and reasoning behind a domain driven design; however, I'm finding it difficult to put all of these together in a real-world application. The lack of complete examples has left me scratching my head. I've found a lot of frameworks and simple examples but nothing so far that really demonstrates how to build a real business application following a DDD.
Using the typical order management system as an example, take the case of order cancellation. In my design I can see an OrderCancellationService with a CancelOrder method which accepts the order # and a reason as parameters. It then has to perform the following 'steps':
Verify that the current user has the necessary permission to cancel an Order
Retrieve the Order entity with the specified order # from the OrderRepository
Verify that the Order may be canceled (should the service interrogate the state of the Order to evaluate the rules or should the Order have a CanCancel property that encapsulates the rules?)
Update the state of the Order entity by calling Order.Cancel(reason)
Persist the updated Order to the data store
Contact the CreditCardService to revert any credit card charges that have already been processed
Add an audit entry for the operation
Of course, all of this should happen in a transaction and none of the operations should be allowed to occur independently. What I mean is, I must revert the credit card transaction if I cancel the order, I cannot cancel and not perform this step. This, imo, suggests better encapsulation but I don't want to have a dependency on the CreditCardService in my domain object (Order), so it seems like this is the responsibility of the domain service.
I am looking for someone to show me code examples how this could/should be "assembled". The thought-process behind the code would be helpful in getting me to connect all of the dots for myself. Thx!
Your domain service may look like this. Note that we want to keep as much logic as possible in the entities, keeping the domain service thin. Also note that there is no direct dependency on credit card or auditor implementation (DIP). We only depend on interfaces that are defined in our domain code. The implementation can later be injected in the application layer. Application layer would also be responsible for finding Order by number and, more importantly, for wrapping 'Cancel' call in a transaction (rolling back on exceptions).
class OrderCancellationService {
private readonly ICreditCardGateway _creditCardGateway;
private readonly IAuditor _auditor;
public OrderCancellationService(
ICreditCardGateway creditCardGateway,
IAuditor auditor) {
if (creditCardGateway == null) {
throw new ArgumentNullException("creditCardGateway");
}
if (auditor == null) {
throw new ArgumentNullException("auditor");
}
_creditCardGateway = creditCardGateway;
_auditor = auditor;
}
public void Cancel(Order order) {
if (order == null) {
throw new ArgumentNullException("order");
}
// get current user through Ambient Context:
// http://blogs.msdn.com/b/ploeh/archive/2007/07/23/ambientcontext.aspx
if (!CurrentUser.CanCancelOrders()) {
throw new InvalidOperationException(
"Not enough permissions to cancel order. Use 'CanCancelOrders' to check.");
}
// try to keep as much domain logic in entities as possible
if(!order.CanBeCancelled()) {
throw new ArgumentException(
"Order can not be cancelled. Use 'CanBeCancelled' to check.");
}
order.Cancel();
// this can throw GatewayException that would be caught by the
// 'Cancel' caller and rollback the transaction
_creditCardGateway.RevertChargesFor(order);
_auditor.AuditCancellationFor(order);
}
}
A slightly different take on it:
//UI
public class OrderController
{
private readonly IApplicationService _applicationService;
[HttpPost]
public ActionResult CancelOrder(CancelOrderViewModel viewModel)
{
_applicationService.CancelOrder(new CancelOrderCommand
{
OrderId = viewModel.OrderId,
UserChangedTheirMind = viewModel.UserChangedTheirMind,
UserFoundItemCheaperElsewhere = viewModel.UserFoundItemCheaperElsewhere
});
return RedirectToAction("CancelledSucessfully");
}
}
//App Service
public class ApplicationService : IApplicationService
{
private readonly IOrderRepository _orderRepository;
private readonly IPaymentGateway _paymentGateway;
//provided by DI
public ApplicationService(IOrderRepository orderRepository, IPaymentGateway paymentGateway)
{
_orderRepository = orderRepository;
_paymentGateway = paymentGateway;
}
[RequiredPermission(PermissionNames.CancelOrder)]
public void CancelOrder(CancelOrderCommand command)
{
using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
{
Order order = _orderRepository.GetById(command.OrderId);
if (!order.CanBeCancelled())
throw new InvalidOperationException("The order cannot be cancelled");
if (command.UserChangedTheirMind)
order.Cancel(CancellationReason.UserChangeTheirMind);
if (command.UserFoundItemCheaperElsewhere)
order.Cancel(CancellationReason.UserFoundItemCheaperElsewhere);
_orderRepository.Save(order);
_paymentGateway.RevertCharges(order.PaymentAuthorisationCode, order.Amount);
}
}
}
Notes:
In general I only see the need for a domain service when a command/use case involves the state change of more than one aggregate. For example, if I needed to invoke methods on the Customer aggregate as well as Order, then I'd create the domain service OrderCancellationService that invoked the methods on both aggregates.
The application layer orchestrates between infrastructure (payment gateways) and the domain. Like domain objects, domain services should only be concerned with domain logic, and ignorant of infrastructure such as payment gateways; even if you've abstracted it using your own adapter.
With regards to permissions, I would use aspect oriented programming to extract this away from the logic itself. As you see in my example, I've added an attribute to the CancelOrder method. You can use an intercepter on that method to see if the current user (which I would set on Thread.CurrentPrincipal) has that permission.
With regards to auditing, you simply said 'audit for the operation'. If you just mean auditing in general, (i.e. for all app service calls), again I would use interceptors on the method, logging the user, which method was called, and with what parameters. If however you meant auditing specifically for the cancellation of orders/payments then do something similar to Dmitry's example.
I'm wondering if it's bad practice to use log4net directly on my domain object... I'll be using ELMAH for my exceptions on the ASP.NET MVC application side, but for some informational purposes I'd like to log some data about the domain model itself.
Given the following domain object:
public class Buyer
{
private int _ID;
public int ID
{
get { return _ID; }
set
{
_ID = value;
}
}
private IList<SupportTicket> _SupportTickets=new List<SupportTicket>();
public IList<SupportTicket> SupportTickets
{
get
{
return _SupportTickets.ToList<SupportTicket>().AsReadOnly();
}
}
public void AddSupportTicket(SupportTicket ticket)
{
if (!SupportTickets.Contains(ticket))
{
_SupportTickets.Add(ticket);
}
}
}
Is adding logging behavior in the AddSupportTicketMethod a bad idea...so essentialy it'd look like this:
public class Buyer
{
protected static readonly ILog log = LogManager.GetLogger(typeof(SupportTicket));
public Buyer()
{
log4net.Config.XmlConfigurator.Configure();
}
private int _ID;
public int ID
{
get { return _ID; }
set
{
_ID = value;
}
}
private IList<SupportTicket> _SupportTickets=new List<SupportTicket>();
public IList<SupportTicket> SupportTickets
{
get
{
return _SupportTickets.ToList<SupportTicket>().AsReadOnly();
}
}
public void AddSupportTicket(SupportTicket ticket)
{
if (!SupportTickets.Contains(ticket))
{
_SupportTickets.Add(ticket);
} else {
log.Warn("Duplicate Ticket Not Added.");
}
}
}
I have used log4net and log4J directly in domain objects. This has good side effects and bad ones.
+: Logging in the domain object is simple and straightforward to code and you know you can take advantage of log4net features.
--: It means the program making use of the domain objects needs to pay attention to log4net configuration, which may or may not be a problem
--: You cannot link your domain object to a different log4net version than the calling program is using. I've seen a lot of conflicts with one item linked against log4net 1.2.0.10 and another linked against an earlier release.
Not logging in your domain object is a bad idea. The alternative is as others have suggested, dependency injection or an external framework (such as commons-logging for log4J) that allows plugging different logging frameworks or creating an interface that does the logging and logging against that interface. (The code using your domain object would need to then supply an appropriate instance of that interface for logging purposes.)
If you are going to log from your domain objects and you use an IOC container which you might want to swap out, I would recommend you use the Service Locator pattern (you could look at the Sharp# architecture for a nice implementation of a SafeServiceLocator that wraps msoft's ServiceLocator with more informative error messages).
I would also like to suggest that you consider whether you want to log the type of error you show in your example. I would tend to want to have the domain object throw an exception in that case and let the caller decide whether that was something that was expected by the application (and hence shouldn't be logged) or whether that represents a situation that the caller wants to deal with in some way.
This is a classic question!
The good way of doing this would be to introduce a class member of ILogger type and abstract the logging into this interface. In your class wherever you do a call to logg something do it through this interface. Then inject this dependency at the run-time with one of the implementation using one of the available IoC container or dependency injection farmeworks. By default you can use log4net implementation of this interface.
Here is a long list of available dependency injection frameworks:
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
I think logging is a cross cutting concern, so it's best done in an aspect-oriented fashion. If you're using a framework like Spring.NET it's available to you.