Howto receive IOrchardHostContainer in a Controller?

Topics: Writing modules
Jul 17, 2011 at 12:10 PM

i tried different ways but i couldnt figure it out :)

anyone can help?

thank you ver much

Jul 17, 2011 at 12:46 PM

okay i answered it myself. you dont need it just resolve the desired component (hold by this container) via constructur & dependency injection

Jul 18, 2011 at 7:30 AM
Edited Jul 18, 2011 at 7:49 AM

next issue!!

I registered a "own" component in the autofac container.

the injection of the logger works fine, but i cant use the overload of
constructor
to resolve   IRepository nor IOrchardServices. 
has anybody an idea, how i could resolve any data access there? thank you
Jul 18, 2011 at 9:31 AM

Can you post some code to demonstrate?

Jul 18, 2011 at 9:49 AM
Edited Jul 18, 2011 at 9:58 AM

sure:

i create a complete new project as dll.

and register it in orchardstarter.cs autofac container.

on resolving the component i will be created if the constructor is just public Test( ), but not if I use public Test( IOrchardServices services) or with IRepository, like in a module.

so i ask myself, how i can get data access.

here example code

namespace TestProject
{
    public class Test: ITest
    {
        private readonly IRepository<ProductPartRecord> _myRecordRepository;
        public IOrchardServices Services { get; set; }

 

//not working
        public Test( IOrchardServices services)
        {
            Services = services;
            Logger = NullLogger.Instance;
        }

        ~Test()
        {
     
        }

//working via injection
        public ILogger logger;
        public ILogger Logger
        {
            get { return logger; }
            set
            {
                logger = value;
                logger.Debug("Logger set");
            }
        }

        public void Log(string Test)
        {
            Logger.Error(Test);
        }

        public void Start()
        {
            Here i want to use orchard dataaccess
        }
    }
}

Jul 18, 2011 at 9:58 AM

None of the constructors found with policy 'Autofac.Core.Activators.Reflection.BindingFlagsConstructorFinder' on type 'TestProject.Test' can be invoked with the available services and parameters:
Constructor 'Void .ctor(Orchard.IOrchardServices)' parameter resolution failed at parameter 'Orchard.IOrchardServices services'.

Jul 18, 2011 at 10:26 AM
notze wrote:

and register it in orchardstarter.cs autofac container.

How are you doing this (I'm guessing you are editing OrchardStarter.cs)? More importantly - why are you doing it in this way?

Jul 18, 2011 at 10:48 AM
Edited Jul 18, 2011 at 10:49 AM

Yes i Just register my Project in OrchardStarter.cs

I'm still trying to find out what possibilities I have with orchard.

I need to have an independant static project with diffrent threads running. no matter what "site" is watched, so a module i think would be the wrong approach.

If I'm wrong please correct me.

In this case a user is possible to enter data via custom orchard module. Based on this data my test-project can calculate and perform tasks.

Jul 18, 2011 at 10:54 AM

Hhmm. It sounds complicated. So are you trying to integrate the calculation step inside Orchard?

Why not implement this calculation or task executing layer as a separate process/service that runs outside or Orchard/IIS? Then, you can communicate with it using named pipes or sockets - and your Orchard module becomes a lot simpler.

Jul 18, 2011 at 11:01 AM
Edited Jul 18, 2011 at 11:15 AM

Thats true, i thought about that, but i also want to take benefit of the datamodel used in the module and the dataaccess of the orchardframework. additionally i participate from the multi tennancy as well, if it runs for every orchard instance.

I already got the suggestion to use the orchard controller as service. but i would loose a lot benefits.

I think im already very close. At least i get the IOrchardHost injected. It cant be that difficult to get data access from there

Jul 18, 2011 at 2:11 PM

I helped myself by setting the IRepository and IOrchardServices from a module in my component. for now that helps even it's very bad style. There has to be an "right" way ?!! :)

Coordinator
Jul 18, 2011 at 7:55 PM

You might want to look at the Orchard command line, as it is spinning up the environment outside of the web server, so that you can execute commands in context. I think it's pretty close to what you are trying to achieve.

Jul 18, 2011 at 9:56 PM
Edited Jul 18, 2011 at 9:59 PM

awesome orchard can do everything

Jul 19, 2011 at 5:40 PM

okay i tried that now. i can create an own console app or service now.

the secret is called CreateStandaloneEnvironment.

with that i can reolve IRepository and IServiceLocator.

Just 2 more questions.

1) wouldnt it make sense to create the standaloneenvironment right at the beginning and use the LocalizationService in Console as well? (all text in the console app could be localized !)

the next one soon :))))

 

Coordinator
Jul 19, 2011 at 7:19 PM

Yes.

Jul 27, 2011 at 8:25 PM

Hi betrandleroy,

the last question in this thread, and maybee my first little codepart for the orchard project :)

 

wouldt it make sense to extend IOrchardhost per default with public IList<ShellContext> Current(); so you you go over lifetimescope and do something like:

var sessionLocator = host.SessionList[0].LifetimeScope.Resolve<ISessionLocator>();

 

greets notze

Aug 16, 2011 at 3:48 PM
Edited Aug 16, 2011 at 3:48 PM

Hi Notze!

Could you please post the code sample where you get the IOrchardServices in the Console Application? 

You advise to use CreateStandaloneEnvironment, but it is contained in the DefaultOrchardHost class, which itself depends on plenty of other interfaces, so it's unclear, how to create instance of that class.

Aug 17, 2011 at 11:20 PM

hey andrey actually i did just a very quick hack, where i modified orchard source to find out whether i can make it work.

i have thrown it away. my previos post has the most important information.

BUT! I still need the same i just did a "is it possible check"!

 

Lets think about to create a service witch offers all we need?

 

Sep 14, 2011 at 7:40 AM
Edited Sep 14, 2011 at 7:46 AM

I measured CreateStandaloneEnvironment and I figured out that it needs at least 700ms. Even if its called the 2nd time.Thats pretty slow if i wanna do a lot of data access.

No I have two options, either create it once and hold it, but that means i have to modify the transaction mechanism, since the transcation is commited, as soon as the using scope arround CreateStandaloneEnvironment is closed, or

to Speed Up somehow the CreateStandaloneEnvironment.

 

What would you suggest?

Sep 20, 2011 at 2:25 PM
Edited Sep 20, 2011 at 2:26 PM

What is the intention for creating shellContext again?

  IWorkContextScope IOrchardHost.CreateStandaloneEnvironment(ShellSettings shellSettings) {
            Logger.Debug("Creating standalone environment for tenant {0}", shellSettings.Name);
            MonitorExtensions();
            BuildCurrent();
            var shellContext = CreateShellContext(shellSettings);          
            return shellContext.LifetimeScope.CreateWorkContextScope();
        }

 

var shellContext = CreateShellContext(shellSettings);             <----------------- takes ~ 700ms but we also call it in  BuildCurrent()->CreateAndActivate() ans save to _current;

Coordinator
Sep 20, 2011 at 5:45 PM

We have already fixed this, it is is a separate branch so that some early adopters can validate it's working fine. The whole tenant provisioning workflow was changed, solving memory and time issues when having several tenants.

You can look at the code here: https://hg01.codeplex.com/forks/sebastienros/multitenants

Sep 20, 2011 at 9:49 PM
Edited Sep 20, 2011 at 9:51 PM

Wow Great! Is there a plan when it will be merged into release version?

Coordinator
Sep 21, 2011 at 12:37 AM

Done, branch 1.x